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 |