这是对Inconsistent Eq和Ord实例的后续问题?.
现在的问题有本质上是:当声明Eq和Ord一个类型的情况下,必须确保compare x y收益EQ当且仅当x == y回报True?创建打破这种假设的实例是危险的吗?这似乎是一个人们可能会假设的自然法则,但它似乎并未在序言中明确说明,与monad或functor法则不同.
基本的回答是:这样做有点危险,因为图书馆可能认为这个法律成立了.
我现在的问题是:是否有任何标准库(特别是Set或Map)做出这样的假设?它是危险的有型不兼容Eq和Ord,只要我只依靠与GHC提供的标准库? (如果仍然可以接受大名单问题,我会问:哪些常用的图书馆会采用这个法律?)
编辑.我的用例类似于原始问题的用例.我有一个自定义实例的类型Eq,我使用了很多.我想要的唯一原因Ord是我可以将它用作a的域Map; 我不关心具体的顺序,也绝不会在代码中明确使用它.因此,如果我可以使用派生的实例Ord,那么我的生活将更容易,我的代码更清晰.
标准前奏中的Ord自身定义要求已经有一个实例:Eq
class (Eq a) => Ord a where
...
Run Code Online (Sandbox Code Playgroud)
因此违反也是错误的
x == y = compare x y == EQ
x /= y = compare x y /= EQ
Run Code Online (Sandbox Code Playgroud)
因为它会违反(从Ord中这些运算符的默认定义).
x <= y = compare x y /= GT
x < y = compare x y == LT
x >= y = compare x y /= LT
x > y = compare x y == GT
Run Code Online (Sandbox Code Playgroud)
编辑:在库中使用
我会很惊讶,如果标准库没有利用Ord的==和/=运营商.特定目的运算符(==,/=,<=,<,>=,>)往往比更为方便compare,所以我希望看到他们在代码中使用mapS或filter秒.
你可以看到在fromAscListWithKey中的==密钥中Data.Map用于守卫.这种特定的功能只召唤出了Eq类,但如果该键也是一个Ord实例Ord的compare将被用于产生的其他功能Map,这是一个假设Eq的==是一样Ord的compare,并测试EQ.
作为一名图书馆程序员,如果任何特殊目的操作员的表现超出compare特定目的,我不会感到惊讶.毕竟,这就是为什么它们是Eq和Ord类的一部分,而不是被定义为所有Eq或Ord实例的多态.即使compare更方便,我也可以指出使用它们.如果我这样做,我可能会定义如下:
compareOp :: (Ord a) => Ordering -> Bool -> a -> a -> Bool
compareOp EQ True = (==)
compareOp EQ False = (/=)
compareOp LT True = (<)
compareOp LT False = (>=)
compareOp GT True = (>)
compareOp GT False = (<=)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
293 次 |
| 最近记录: |