我制作了一个图像处理模块,将Pixel
类型定义为Color
和Location
。 Pixel
,Color
和Location
派生Eq
,因为我可能想比较多个图片之间的像素。
Eq
符合我对比较像素的需求,看看它们是否完全相同,这就是我想要的。实例化Eq
的一个奇怪的副作用是,将2个不同的像素与Location
或<=
的{{1}}进行比较会产生>=
,但{{1} {} {},True
和False
。
==
然后在 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 同时是Ord
和Pixel
b 而不是Location
,{{1} },或>=
。
编辑:如果有人想要使用这些代码中的任何一个,我将包含解决问题的代码片段。请务必从<=
定义中删除==
。
<
这样只允许比较>
。请享用! :)
答案 0 :(得分:9)
我感到困惑的部分是
a
如何大于或等于,小于或等于b
而不等于,小于或大于。{/ p>
通过引入Ord
的自定义Pixel
实例,同时仍然可以推导出来
Eq
,你有一个有趣的结果:
这会使事情表现得很奇怪,因为有些东西会比较
EQ
(仅基于相同的位置),同时,如果您
测试与(==)
的相等性,值是不等的,因为颜色是
也包括在内。
基本上你已经使Eq
和Ord
个实例不健全了。
导出Eq
和Ord
,获得完全的结构平等和
排序或手动编写丢弃颜色信息的Eq
实例,
正如您现有的Ord
实例所做的那样。
答案 1 :(得分:3)
因为您的Ord实例忽略了颜色,但您的派生Eq实例不会。 a == b
为false,因为 ==
是Eq类型类的方法,派生方法将考虑颜色。
a <= b
是正确的,因为 <=
是Ord类型类的一部分,并且您的比较实现会忽略颜色,这意味着 compare a b == EQ
如果a和b具有相同的位置,无论其颜色如何。