title: Implementing custom comparison with CustomComparison and CustomEquality in F# tuple
body: <p>I'm here to ask a specific topic - I really found few info about this on the web.
  I'm implementing a F# version of Minimax algorithm. The problem I'm having now is that I want to compare Leaf of my tree (data structure below). Searching the erros the VS gave to me I arrived to something like this:</p>
  
  <p>The tree type I used to have: </p>
  
  <pre><code>type TreeOfPosition =
      | LeafP   of Position
      | BranchP of Position * TreeOfPosition list
  </code></pre>
  
  <p>and the temptative for implementing the IComparable</p>
  
  <pre><code>type staticValue = int
  [&lt;CustomEquality;CustomComparison&gt;]
  type TreeOfPosition =
      | LeafP   of Position * staticValue
      | BranchP of Position * TreeOfPosition list
  
      override x.Equals(yobj) = 
          match yobj with
          | :? TreeOfPosition as y -&gt; (x = y)
          | _ -&gt; false
  
      override x.GetHashCode() = hash (x)
      interface System.IComparable with
          member x.CompareTo yobj =
              match yobj with
              | :? TreeOfPosition as y -&gt; compare (x) (y)
              | _ -&gt; invalidArg "yobj" "cannot compare value of different types"
  </code></pre>
  
  <p>In the end, I just wanna get the max (and the min) of a list of LeafP by its static value (calculate in other function). </p>
  
  <p>The code above compiles. However testing with this:</p>
  
  <pre><code>let p = new Position()
  p.Add(1,BLACK)
  let a = LeafP(p,1)
  let b = LeafP(p,2)
  
  let biger = compare a b
  printf "%d" biger
  </code></pre>
  
  <p>I got a System.StackOverflowException in the "| :? TreeOfPosition as y -> compare (x) (y)" line in the override of the GetHashCode.</p>
  
  <p>I have a thread in the hubfs.net (<a href="http://cs.hubfs.net/forums/thread/15891.aspx" rel="noreferrer">http://cs.hubfs.net/forums/thread/15891.aspx</a>) with I'm discussing my Minimax. Here you can find my lastest code (<a href="http://www.inf.ufrgs.br/~pmdusso/works/Functional_Implementation_Minimax_FSharp.htm" rel="noreferrer">http://www.inf.ufrgs.br/~pmdusso/works/Functional_Implementation_Minimax_FSharp.htm</a>)</p>
  
  <p>Thanks in advance, </p>
  
  <p>Pedro Dusso</p>
  
  <p>Well, I understood very clearly the idea but I can’t make it work. Remembering that I want to get the leaf with the max static value from a list of leafs (“List.max” :P), I think implementing the <code>CompareTo</code> or <code>Equals</code> will let the List.max works on them, correct?
  I compose the things like this:</p>
  
  <pre><code>let mycompare x y = 
    match x, y with
    // Compare values stored as part of your type
    | LeafP(_, n1), LeafP(_, n2) -&gt; compare n1 n2
    //| BranchP(_, l1), BranchP(_, l2) -&gt; compare l1 l2 //I do not need Branch lists comparison
    | _ -&gt; 0 // or 1 depending on which is list...
  
  [&lt; CustomEquality;CustomComparison &gt;]
  type TreeOfPosition =
      | LeafP   of Position * int
      | BranchP of Position * TreeOfPosition list
  
      override x.Equals(yobj) = 
         match yobj with
         | :? TreeOfPosition as y -&gt; (x = y)
         | _ -&gt; false
  
      override x.GetHashCode() = hash (x)
      interface System.IComparable with
         member x.CompareTo yobj = 
            match yobj with 
            | :? TreeOfPosition as y -&gt; mycompare x y
            | _ -&gt; invalidArg "yobj" "cannot compare value of different types" 
  </code></pre>
  
  <p>The problems I’m having arranging the functions this way is:</p>
  
  <p>1) The pattern discriminator 'LeafP' is not defined (with LeafP red-underlined)</p>
  
  <p>2) (77,39): error FS0039: The value or constructor 'mycompare' is not defined, when I try a ALT  ENTER this message appear in my F# Interactive. The position {77,39} corresponds to the beginning of mycompare call (in GetHashCode).</p>
  
  <p>What I’m doing wrong? What can I do better? </p>
  
  <p>Thanks very much,</p>
  
  <p>Pedro Dusso</p>
  
  <p><strong>EDIT 3 - Solved</strong></p>
  
  <p>Yes! I manage your answer to work finaly!</p>
  
  <p>The final code is here:</p>
  
  <pre><code>[&lt;CustomEquality;CustomComparison&gt;]
  type TreeOfPosition =
      | LeafP   of Position * int
      | BranchP of Position * TreeOfPosition list
  
      //Func: compare
      //Retu: -1: first parameter is less than the second
      //       0: first parameter is equal to the second
      //       1: first parameter is greater than the second
      static member mycompare (x, y) = 
          match x, y with
          // Compare values stored as part of your type
          | LeafP(_, n1), LeafP(_, n2) -&gt; compare n1 n2
          | _ -&gt; 0 // or 1 depending on which is list...
  
      override x.Equals(yobj) = 
          match yobj with
          | :? TreeOfPosition as y -&gt; (x = y)
          | _ -&gt; false
  
      override x.GetHashCode() = hash (x)
      interface System.IComparable with
         member x.CompareTo yobj = 
            match yobj with 
            | :? TreeOfPosition as y -&gt; TreeOfPosition.mycompare(x, y)
            | _ -&gt; invalidArg "yobj" "cannot compare value of different types" 
  </code></pre>
  
  <p>Thanks for the feedback!</p>
  
  <p>Pedro Dusso</p>