haskell - Eq 实例有一些奇怪的比较

标签 haskell comparison ghc typeclass deriving

我制作了一个图像处理模块,它定义了 Pixel键入 ColorLocation . 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 to b without being equal, less than, or greater.



通过介绍您的自定义 Ord Pixel 的实例, 同时仍然推导Eq ,你有一个有趣的结果:
  • 像素将具有完全的结构相等性,基于它们的颜色和位置
  • 但是,为了给他们下订单,您要求忽略颜色。

  • 这将使事情变得奇怪,因为有些事情会比较EQ (仅基于具有相同的位置),同时,如果您
    (==) 测试是否相等,值将不相等,因为颜色是
    也包括在内。

    基本上你已经制作了EqOrd不健全的实例。

    要么派生EqOrd ,获得完全的结构平等和
    订购,或手动编写 Eq丢弃颜色信息的实例,
    作为您现有的Ord实例确实如此。

    关于haskell - Eq 实例有一些奇怪的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5766372/

    相关文章:

    c++ - Haskell ghc Visual Studio DLL 奇怪的行为

    Haskell:通过在 C 函数中创建代数数据类型进行编码

    linux - Cabal 无法在 Linux 上安装 network-2.6.3.1

    c - 如何检查一个字符串是否以C中的另一个字符串开头?

    java - 比较两个整数的值

    haskell - Acid-state:更新的 MonadState 实例

    haskell - 如何在 WAI/scotty 中记录整个 HTTP 请求?

    haskell - 防止无意中使用不同类型的类实例

    datetime - 如何为 Progress 4GL 查询中的每个循环添加日期条件?

    haskell - 约束类型在哪里定义?