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:
The tree type I used to have:
type TreeOfPosition =
| LeafP of Position
| BranchP of Position * TreeOfPosition list
and the temptative for implementing the IComparable
type staticValue = int
[<CustomEquality;CustomComparison>]
type TreeOfPosition =
| LeafP of Position * staticValue
| BranchP of Position * TreeOfPosition list
override x.Equals(yobj) =
match yobj with
| :? TreeOfPosition as y -> (x = y)
| _ -> false
override x.GetHashCode() = hash (x)
interface System.IComparable with
member x.CompareTo yobj =
match yobj with
| :? TreeOfPosition as y -> compare (x) (y)
| _ -> invalidArg "yobj" "cannot compare value of different types"
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).
The code above compiles. However testing with this:
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
I got a System.StackOverflowException in the "| :? TreeOfPosition as y -> compare (x) (y)" line in the override of the GetHashCode.
I have a thread in the hubfs.net (http://cs.hubfs.net/forums/thread/15891.aspx) with I'm discussing my Minimax. Here you can find my lastest code (http://www.inf.ufrgs.br/~pmdusso/works/Functional_Implementation_Minimax_FSharp.htm)
Thanks in advance,
Pedro Dusso
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 CompareTo
or Equals
will let the List.max works on them, correct?
I compose the things like this:
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 //I do not need Branch lists comparison
| _ -> 0 // or 1 depending on which is list...
[< CustomEquality;CustomComparison >]
type TreeOfPosition =
| LeafP of Position * int
| BranchP of Position * TreeOfPosition list
override x.Equals(yobj) =
match yobj with
| :? TreeOfPosition as y -> (x = y)
| _ -> false
override x.GetHashCode() = hash (x)
interface System.IComparable with
member x.CompareTo yobj =
match yobj with
| :? TreeOfPosition as y -> mycompare x y
| _ -> invalidArg "yobj" "cannot compare value of different types"
The problems I’m having arranging the functions this way is:
1) The pattern discriminator 'LeafP' is not defined (with LeafP red-underlined)
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).
What I’m doing wrong? What can I do better?
Thanks very much,
Pedro Dusso
EDIT 3 - Solved
Yes! I manage your answer to work finaly!
The final code is here:
[<CustomEquality;CustomComparison>]
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) -> compare n1 n2
| _ -> 0 // or 1 depending on which is list...
override x.Equals(yobj) =
match yobj with
| :? TreeOfPosition as y -> (x = y)
| _ -> false
override x.GetHashCode() = hash (x)
interface System.IComparable with
member x.CompareTo yobj =
match yobj with
| :? TreeOfPosition as y -> TreeOfPosition.mycompare(x, y)
| _ -> invalidArg "yobj" "cannot compare value of different types"
Thanks for the feedback!
Pedro Dusso