Я здесь, чтобы задать конкретную тему - я действительно нашел немного информации об этом в Интернете.
Я реализую F # версию алгоритма Minimax. Сейчас у меня проблема в том, что я хочу сравнить Leaf моего дерева (структура данных ниже). В поисках ошибок, которые дала мне VS, я пришел к чему-то вроде этого:
Тип дерева, который у меня был:
type TreeOfPosition =
| LeafP of Position
| BranchP of Position * TreeOfPosition list
и соблазн для реализации 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"
В конце я просто хочу получить максимум (и минимум) списка LeafP по его статическому значению (вычислить в другой функции).
Код выше компилируется. Однако тестирование с этим:
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
Я получил System.StackOverflowException в строке "|:? TreeOfPosition как y -> сравнить (x) (y)" в переопределении GetHashCode.
У меня есть нить в hubfs.net (http://cs.hubfs.net/forums/thread/15891.aspx), с которой я обсуждаю свой минимакс. Здесь вы можете найти мой последний код (http://www.inf.ufrgs.br/~pmdusso/works/Functional_Implementation_Minimax_FSharp.htm)
Заранее спасибо,
Педро Дуссо
Ну, я очень ясно понял идею, но не могу заставить ее работать. Помня, что я хочу получить лист с максимальным статическим значением из списка листов («List.max»: P), я думаю, что реализация CompareTo
или Equals
позволит List.max работать с ними, правильно ?
Я сочиняю такие вещи:
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"
У меня проблемы с организацией функций следующим образом:
1) Дискриминатор шаблона 'LeafP' не определен (с красной линией LeafP)
2) (77,39): ошибка FS0039: значение или конструктор 'mycompare' не определены, когда я пытаюсь ALT ENTER, это сообщение появляется в моем F # Interactive. Позиция {77,39} соответствует началу вызова mycompare (в GetHashCode).
Что я делаю не так? Что я могу сделать лучше?
Большое спасибо,
Педро Дуссо
РЕДАКТИРОВАТЬ 3 - Решено
Да! Я управляю твоим ответом на работу окончательно!
Финальный код здесь:
[<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"
Спасибо за отзыв!
Педро Дуссо