Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

do I need custom Ord instance if I have custom Eq?

I had a data type that used to derive generic Eq and Ord:

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

Then I created my own instance of 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'

I am not sure if this breaks the Ord behavior and whether I need to create an instance of Ord too. Could someone please clarify?

like image 555
akonsu Avatar asked Jan 08 '23 06:01

akonsu


1 Answers

as I said in my comment you break the Ord laws here:

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

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

as now a == b and also a < b:

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

see: Ord is supposed to be a total order and one law for those is

a < b if and only if a ≤ b and a ≠ b

so of course you should fix it with the obvious choice for your own instance:

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
like image 88
Random Dev Avatar answered Jan 15 '23 19:01

Random Dev