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 |