
20 Aug
2014
20 Aug
'14
5:12 a.m.
There are two cases I can think of where it would also change the semantics of the code:
1. An Eq instance that doesn't obey the reflective property (not recommended):
data BadEq = BadEq instance Eq BadEq where BadEq == BadEq = False
2. Eq instances intended to avoid timing attacks, by always comparing the entire data structure.
newtype SlowEq a = SlowEq [a] instance Eq a => Eq (SlowEq a) where SlowEq x == SlowEq y = slowAnd $ length x == length y : zipWith (==) x y
slowAnd = loop True where loop !x [] = x loop !x (!y:ys) = loop (x && y) ys
Third case that would change the semantics: 3. Non-terminating evaluation of a value: let x = [1..] in x == x