gpt4 book ai didi

.net - 在具有元组的可区分联合上重载相等 F# 运算符会产生意外结果

转载 作者:行者123 更新时间:2023-12-04 18:40:23 24 4
gpt4 key购买 nike

好的,为了使复杂的标题更加清晰:我有一个单例联合,它是一个通用元组。该类型还重载了相等运算符,目的是制作类似 Edge (1, 2) 的内容。相当于 Edge (2, 1) .

type Edge<'a> = Edge of 'a * 'a
with
static member (=) (e1: Edge<_>, e2: Edge<_>) =
match e1, e2 with
| Edge(a,b), Edge(c,d) ->
(a = c && b = d) || (a = d && b = c)

但是,当我创建两个应该相等的 Edge 类型值并比较它们时,它返回 false。
> let e1 = Edge (1,2);;

val e1 : Edge<int> = Edge (1,2)

> let e2 = Edge (2,1);;

val e2 : Edge<int> = Edge (2,1)

> e1 = e2;;

val it : bool = false

我不知道这里实际发生了什么。等式 (=) 运算符是否有什么特别之处使它比其他运算符更复杂?

最佳答案

所以错误信息中有一个提示(你没有发布)

warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead.



您实际上可以通过添加 printf 来检查调用您的原始代码,您会发现它实际上从未被调用过。

那么你试试这个:
type Edge<'a> = Edge of 'a * 'a
with
override x.Equals (y: obj ) =
match y with
| :? Edge<'a> as e ->
match x,e with
|Edge(a,b),Edge(c,d)->(a = c && b = d) || (a = d && b = c)
| _ -> false

这也失败了。然后编译器错误消息会引导您查看更多错误消息,直到您到达
[<CustomEquality;NoComparison>]
type Edge<'a when 'a:equality> = Edge of 'a * 'a
with
override x.Equals (y: obj ) =
match y with
| :? Edge<'a> as e ->
match x,e with
|Edge(a,b),Edge(c,d)->(a = c && b = d) || (a = d && b = c)
| _ -> false

这工作得很好。 equals 函数比许多其他运算符稍微复杂一些,因此覆盖它需要更多的努力。

关于.net - 在具有元组的可区分联合上重载相等 F# 运算符会产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24443475/

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