我有一个用于派生通用Eq
和Ord
的数据类型:
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
的实例。请有人澄清一下吗?
答案 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