Ticket #3866 (closed bug: fixed)
Constr Eq instance should have better documentation or semantics
|Reported by:||batterseapower||Owned by:||dreixel|
|Type of failure:||None/Unknown||Difficulty:|
|Test Case:||Blocked By:|
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://firstname.lastname@example.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.