F#Set未返回正确的差值。我的CompareTo实现可能存在问题

F#Set未返回正确的差值。我的CompareTo实现可能存在问题,f#,F#,我从两套开始,abc和zxc。“未修改”的项目数(1)正确 集合abc有两个项目,其中一个是未修改的项目 let unmodified=Set.intersect abc zxc 设newAndModified=a-未修改 我希望newAndModified包含一项,但它有两项。它似乎是与abc相同的集合 尽管我的Set.intersect工作得很好,但其他Set函数并没有返回正确的结果,我相信我为这个对象实现CompareTo的方式有问题 类型栏= {Id:int 名称:string } [

我从两套开始,abc和zxc。“未修改”的项目数(1)正确
集合abc有两个项目,其中一个是未修改的项目

let unmodified=Set.intersect abc zxc
设newAndModified=a-未修改
我希望newAndModified包含一项,但它有两项。它似乎是与abc相同的集合

尽管我的Set.intersect工作得很好,但其他Set函数并没有返回正确的结果,我相信我为这个对象实现CompareTo的方式有问题

类型栏=
{Id:int
名称:string
}
[]
Foo型=
{Name:string
Id:int
酒吧:酒吧列表
}
覆盖x.Equals(y)=
匹配
| :? Foo as y->x.Id等于y.Id
&&x.Name等于y.Name
&&x.bar.Head.Name等于y.bar.Head.Name
|_u->invalidArg“y”无法将对象与非Foo对象进行比较
成员x.CompareTo(y:obj)=
匹配
|空->空参数“y”
| :? Foo as y->x.CompareTo(y)
|->invalidArg“y”必须是Foo的实例
成员x.CompareTo(y:Foo)=
将x等于y与
|正确->0
|错误->-1
接口i可与
成员x.CompareTo y=x.CompareTo y
接口系统.i可与
成员x.CompareTo y=
匹配
| :? Foo as y->(x:>i可比较)。与y比较
|->invalidArg“y”无法比较不同类型的值

您的
比较
实现在这里肯定行不通。当两个对象相等时返回0(这很好),但如果它们不相等,则始终返回-1。这意味着第一个比最后一个小

然而,这是行不通的。如果您有对象
a
b
,那么您的比较结果是
a
b
(这违反了订购关系的要求)

F#集要求对象是可排序的,因为它将数据保存在一个平衡的树中(较小的元素在左边,较大的元素在右边)——因此使用总是返回-1的
CompareTo
,它最终创建了一个毫无意义的树

为什么要为类型实现自定义比较?我想你这样做只是为了考虑一些领域而忽略了其他一些领域。在这种情况下,实际上有一个很好的技巧,就是用感兴趣的字段创建一个元组,并调用内置的
hash
compare
函数。例如:

compare (x.Id, x.Name, x.Bars.Head.Name)
        (y.Id, y.Name, y.Bars.Head.Name)

这将在元组上使用默认的F#比较,这是一种正确定义的排序关系。

您的
比较到
实现在这里肯定不起作用。当两个对象相等时返回0(这很好),但如果它们不相等,则始终返回-1。这意味着第一个比最后一个小

然而,这是行不通的。如果您有对象
a
b
,那么您的比较结果是
a
b
(这违反了订购关系的要求)

F#集要求对象是可排序的,因为它将数据保存在一个平衡的树中(较小的元素在左边,较大的元素在右边)——因此使用总是返回-1的
CompareTo
,它最终创建了一个毫无意义的树

为什么要为类型实现自定义比较?我想你这样做只是为了考虑一些领域而忽略了其他一些领域。在这种情况下,实际上有一个很好的技巧,就是用感兴趣的字段创建一个元组,并调用内置的
hash
compare
函数。例如:

compare (x.Id, x.Name, x.Bars.Head.Name)
        (y.Id, y.Name, y.Bars.Head.Name)

这将在元组上使用默认的F#比较,这是一种正确定义的排序关系。

谢谢谢谢谢谢!!!!!你是对的,我实现了自定义比较来忽略一些字段。你的回答像做梦一样奏效。此外,您对我的CompareTo实现不起作用的原因也进行了很好的解释!谢谢谢谢谢谢谢谢!!!!!你是对的,我实现了自定义比较来忽略一些字段。你的回答像做梦一样奏效。此外,您对我的CompareTo实现不起作用的原因也进行了很好的解释!