如果我有自定义Eq,我需要自定义Ord实例吗?

时间:2015-10-30 05:57:03

标签: haskell typeclass

我有一个用于派生通用EqOrd的数据类型:

data State = State (Set String) (Set String) deriving (Eq, Ord)

然后我创建了自己的Eq实例:

data State = State (Set String) (Set String) deriving Ord

instance Eq State where
    (State s0 s1) == (State s0' s1') =
        Set.union s0 s1 == Set.union s0' s1'

我不确定这是否会破坏Ord行为以及是否需要创建Ord的实例。请有人澄清一下吗?

1 个答案:

答案 0 :(得分:9)

正如我在评论中所说,你在这里违反了Ord法律:

a :: State
a = State (Set.fromList ["A"]) (Set.fromList ["B"])

b :: State
b = State (Set.fromList ["B"]) (Set.fromList ["A"])     

现为a == b以及a < b

λ> a == b
True
λ> a < b
True
λ> b < a
False

请参阅:Ord应该是total order,其中一条法则是

  

a&lt; b当且仅当a≤b且a≠b

所以当然你应该用你自己实例的明显选择来修复它:

instance Ord State where
  (State s0 s1) <= (State s0' s1') =
    Set.union s0 s1 <= Set.union s0' s1'

λ> a == b
True
λ> b < a
False
λ> a < b
False