我制作了一个图像处理模块,它定义了 Pixel
键入 Color
和 Location
. Pixel
, Color
, 和 Location
导出 Eq
,因为我可能想比较多个图像之间的像素。Eq
适合我比较像素以查看它们是否完全相同的需要,这正是我想要的。实例化的奇怪副作用 Eq
是比较 2 个不同的像素与相同的 Location
与 <=
或 >=
结果 True
, 但是 False
对于 ==
, <
, 和 >
.
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
然后在 ghci 中进行一些测试。
>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
看来我的定义
Ord
对于 Pixel
影响了这些比较,这是可以理解的。 d 表明 Location
影响比较。我感到困惑的部分是 a 如何是 >=
和 <=
b 不是 ==
, <
, 或 >
.编辑:如果有人想使用任何这段代码,我将包含这个解决问题的片段。请务必删除
Eq
来自 Pixel
定义。instance Eq Pixel where
(Pixel _ a) == (Pixel _ b) = a == b
(Pixel _ a) /= (Pixel _ b) = a /= b
这允许比较
Location
只要。享受! :)
最佳答案
The part I'm confused about is how
a
is both greater than or equal to and less than or equal tob
without being equal, less than, or greater.
通过介绍您的自定义
Ord
Pixel
的实例, 同时仍然推导Eq
,你有一个有趣的结果:这将使事情变得奇怪,因为有些事情会比较
EQ
(仅基于具有相同的位置),同时,如果您用
(==)
测试是否相等,值将不相等,因为颜色是也包括在内。
基本上你已经制作了
Eq
和 Ord
不健全的实例。要么派生
Eq
和 Ord
,获得完全的结构平等和订购,或手动编写
Eq
丢弃颜色信息的实例,作为您现有的
Ord
实例确实如此。
关于haskell - Eq 实例有一些奇怪的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5766372/