gpt4 book ai didi

f# - 在 F# 元组中使用 CustomComparison 和 CustomEquality 实现自定义比较

转载 作者:行者123 更新时间:2023-12-04 04:13:54 28 4
gpt4 key购买 nike

我在这里问一个特定的话题 - 我真的在网上找到了很少的信息。
我正在实现 Minimax 算法的 F# 版本。我现在遇到的问题是我想比较我的树的叶子(下面的数据结构)。搜索 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

我在 GetHashCode 的覆盖中的“| :? TreeOfPosition as y -> compare (x) (y)”行中得到了 System.StackOverflowException。

我在 hubfs.net ( http://cs.hubfs.net/forums/thread/15891.aspx ) 中有一个线程,我正在讨论我的 Minimax。在这里你可以找到我最新的代码 ( http://www.inf.ufrgs.br/~pmdusso/works/Functional_Implementation_Minimax_FSharp.htm )

提前致谢,

佩德罗·杜索

嗯,我非常清楚这个想法,但我无法让它发挥作用。记住我想从叶子列表(“List.max”:P)中获取具有最大静态值的叶子,我想实现 CompareToEquals会让 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 - 已解决

是的!我管理你的答案工作finaly!

最终代码在这里:
[<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"

感谢您的反馈!

佩德罗·杜索

最佳答案

首先,您会收到异常,因为 compare函数调用 CompareTo您正在比较的值的方法(即 x.ComaperTo(y) )。您使用 compare 比较的值在 CompareTo 的自定义实现中是您被要求比较的值(由运行时),因此这会导致堆栈溢出。

通常的实现方式 CompareToEquals是只比较您存储在您的类型中的一些值。例如,你可以这样写:

编辑 : 你可以写一个辅助函数mycopare进行比较(或者您可以简单地更改 CompareTo 实现)。但是,如果要使用函数,则需要将其移动到类型声明中(以便它知道类型 - 请注意,在 F# 中,声明的顺序很重要!)

一种写法是这样的:

[<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"

这会起作用,因为每次调用 compare只需要部分数据,所以你取得了一些进展。

关于f# - 在 F# 元组中使用 CustomComparison 和 CustomEquality 实现自定义比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3093408/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com