Implementing custom comparison with CustomComparison and CustomEquality in F# tuple

后端 未结 1 809
遥遥无期
遥遥无期 2021-02-20 17:19

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 wan

相关标签:
1条回答
  • 2021-02-20 17:59

    First of all, you're getting the exception because the compare function calls the CompareTo method of the values you're comparing (that is x.ComaperTo(y)). The values you're comparing using compare in the custom implementation of CompareTo are the values that the you are asked to compare (by the runtime), so this causes the stack overflow.

    The usual way to implement CompareTo or Equals is to compare only some values that you store in your type. For example, you could write something like this:

    EDIT: You can write a helper function mycopare to do the comparison (or you could simply change the CompareTo implementation). However, if you want to use a function, you need to move it inside the type declaration (so that it knows about the type - note that in F#, the order of declaration matters!)

    One way of writing it is this:

    [<CustomEquality; CustomComparison >] 
    type TreeOfPosition = 
      | LeafP   of Position * int 
      | BranchP of Position * TreeOfPosition list 
    
      override x.Equals(yobj) =  
         match yobj with 
         | :? TreeOfPosition as y -> 
            // TODO: Check whether both y and x are leafs/branches
            // and compare their content (not them directly)
         | _ -> false 
      override x.GetHashCode() = // TODO: hash values stored in leaf/branch
    
      interface System.IComparable with 
         member x.CompareTo yobj =  
    
           // Declare helper function inside the 'CompareTo' member
           let mycompare x y = 
             match x, y with
             // Compare values stored as part of your type
             | LeafP(_, n1), LeafP(_, n2) -> compare n1 n2
             | BranchP(_, l1), BranchP(_, l2) -> compare l1 l2
             | _ -> -1 // or 1 depending on which is list...
    
           // Actual implementation of the member
           match yobj with 
           | :? TreeOfPosition as y -> mycompare x y
           | _ -> invalidArg "yobj" "cannot compare value of different types" 
    

    This would work, because every call to compare takes only some part of the data, so you're making some progress.

    0 讨论(0)
提交回复
热议问题