Derived instances of Data lack dataCast1 and dataCast2
In the following code snippet:
data MyMaybe a = MyNothing | MyJust a deriving (Data, Typeable)
test1 :: ()
test1 = undefined `ext1Q` (\ (Just _) -> ()) $ Just ()
test1' :: ()
test1' = undefined `ext1Q` (\ (MyJust _) -> ()) $ MyJust ()
test1 evaluates to () as expected, but test1' evaluates to bottom.
The same happens for dataypes of kind * -> * -> *:
newtype Q r a = Q { unQ :: a -> r }
ext2Q :: (Data d, Typeable2 t)
=> (d -> q) -> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q) -> d -> q
ext2Q def ext arg =
case dataCast2 (Q ext) of
Just (Q ext') -> ext' arg
Nothing -> def arg
data MyPair a b = MyPair a b deriving (Data, Typeable)
test2 :: ()
test2 = undefined `ext2Q` (\(_,_) -> ()) $ ((),())
test2' :: ()
test2' = undefined `ext2Q` (\(MyPair _ _) -> ()) $ MyPair () ()
test2 evaluates to () as expected, but test2' evaluates to bottom. Note that we need to define ext2Q, which uses dataCast2. ext1Q, which is defined in the library, uses dataCast1.
This happens because the derived Data instances for !MyMaybe and !MyPair are missing a definition for dataCast1 and dataCast2, respectively. The Data instances for Maybe and (,) are:
instance Data a => Data (Maybe a) where
...
dataCast1 f = gcast1 f
instance (Data a, Data b) => Data (a,b) where
...
dataCast2 f = gcast2 f
Trac metadata
Trac field | Value |
---|---|
Version | 6.10.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |