On Wed, Aug 20, 2014 at 11:28 AM, Johan Tibell <johan.tibell@gmail.com> wrote:
On Wed, Aug 20, 2014 at 10:23 AM, Erik Hesselink <hesselink@gmail.com> wrote:
As I understood, the question was if GHC would first compare pointers,
and only call the Eq instance if the pointers are not equal. I guess
this would be safe, but I don't think GHC does such a thing.I think the reason it isn't done is that it's not always an optimization. We do it manually in e.g. bytestring.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 = BadEqinstance Eq BadEq whereBadEq == BadEq = False2. 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) whereSlowEq x == SlowEq y = slowAnd $ length x == length y : zipWith (==) x y
slowAnd =loop Truewhereloop !x [] = xloop !x (!y:ys) = loop (x && y) ys(Note: not actually tested.) It's difficult for me to imagine a case though where a timing attack could result on two data structures sharing the same pointer; usually we'd be talking about comparing two ByteStrings or Texts that come from very different sources.
Michael
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe