Eq实例有一些奇怪的比较

时间:2011-04-23 19:26:12

标签: haskell comparison ghc typeclass deriving

我制作了一个图像处理模块,将Pixel类型定义为ColorLocationPixelColorLocation派生Eq,因为我可能想比较多个图片之间的像素。

Eq符合我对比较像素的需求,看看它们是否完全相同,这就是我想要的。实例化Eq的一个奇怪的副作用是,将2个不同的像素与Location<=的{​​{1}}进行比较会产生>=,但{{1} {} {},TrueFalse

==

然后在 ghci 进行一些测试。

<

似乎我对>的定义data Color = Color { red :: Int , green :: Int , blue :: Int , alpha :: Int } deriving ( Show, Eq ) data Location = Location { x :: Int , y :: Int } deriving ( Show, Eq, Ord ) data Pixel = Pixel { color :: Color , location :: Location } deriving ( Show, Eq ) instance Ord Pixel where compare (Pixel _ a) (Pixel _ b) = compare a b 影响了这些比较,这是可以理解的。 d 表明>let a = Pixel (Color 0 0 0 255) (Location 0 0) >let b = Pixel (Color 0 0 1 255) (Location 0 0) >let c = Pixel (Color 0 0 0 255) (Location 0 0) >let d = Pixel (Color 0 0 0 255) (Location 0 1) >a == b False >a /= b True >a < b False >a > b False >a <= b True >a >= b True >a == c True >a /= c False >a > c False >a < c False >a >= c True >a <= c True >a == d False >a /= d True >a > d False >a < d True a >= d False a <= d True 会影响比较。我感到困惑的部分是 a 同时是OrdPixel b 而不是Location,{{1} },或>=

编辑:如果有人想要使用这些代码中的任何一个,我将包含解决问题的代码片段。请务必从<=定义中删除==

<

这样只允许比较>。请享用! :)

2 个答案:

答案 0 :(得分:9)

  

我感到困惑的部分是a如何大于或等于,小于或等于b而不等于,小于或大于。{/ p>

通过引入Ord的自定义Pixel实例,同时仍然可以推导出来 Eq,你有一个有趣的结果:

  • 像素将根据其颜色和位置具有完全结构相等性
  • 然而,为了给他们一个订单,你要求忽略它的颜色。

这会使事情表现得很奇怪,因为有些东西会比较 EQ(仅基于相同的位置),同时,如果您 测试与(==)的相等性,值是不等的,因为颜色是 也包括在内。

基本上你已经使EqOrd个实例不健全了。

导出EqOrd,获得完全的结构平等和 排序或手动编写丢弃颜色信息的Eq实例, 正如您现有的Ord实例所做的那样。

答案 1 :(得分:3)

因为您的Ord实例忽略了颜色,但您的派生Eq实例不会。 a == b 为false,因为 == 是Eq类型类的方法,派生方法将考虑颜色。
a <= b 是正确的,因为 <= 是Ord类型类的一部分,并且您的比较实现会忽略颜色,这意味着 compare a b == EQ 如果a和b具有相同的位置,无论其颜色如何。