Skip to content

Constr Eq instance should have better documentation or semantics

The following code doesn't do what you expect:

data WithData = forall a. Data a => WithData a

tupleDataCast :: Data a => ([WithData] -> c) -> a -> Maybe c
tupleDataCast f x | Just (s, _) <- find ((toConstr x ==) . snd) tuples
                  = trace (show (toConstr x, s)) $ Just (f [gmapQi i WithData x | i <- [0..s - 1]])
                  | otherwise = Nothing
  where tuples = [2..] `zip` [toConstr ((), ()), toConstr ((), (), ()), toConstr ((), (), (), ()), toConstr ((), (), (), (), ()), toConstr ((), (), (), (), (), ())]

The reason is that, for example:

Prelude Data.Data> toConstr False == toConstr ()
True
Prelude Data.Data> toConstr True == toConstr ()
False

The Constr data type is only compared on the index. The DataType information in the Constr is totally ignored. This is very surprising behaviour!

According to a mailing list thread (http://www.mail-archive.com/glasgow-haskell-bugs@haskell.org/msg08207.html) this is done for efficiency reasons.

Either the documentation should mention this behaviour, or the Eq instance should be fixed. My preference is for the latter -- though existing expectations of Constr == efficiency and semantics may be too entrenched to change the behaviour now.

Trac metadata
Trac field Value
Version 6.12.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries (other)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information