I have a GADT defined like (abbreviated),
{-# LANGUAGE StandaloneDeriving #-}
data D t where
C :: t -> D t
R :: D b -> D (Either a b)
deriving instance Show t => Show (D t)
The compiler correctly complains that it cannot derive Show for R. In this case, we have that (Either a b) is of class Show, but we can't know that this is true iff b is of class Show. The error message is,
Could not deduce (Show b) from the context (t ~ Either a b)
arising from a use of `showsPrec' at tmp.hs:37:0-37
Possible fix: add (Show b) to the context of the constructor `R'
In the second argument of `(.)', namely `(showsPrec 11 b1)'
In the second argument of `showParen', namely
`((.) (showString "R ") (showsPrec 11 b1))'
In the expression:
showParen ((a >= 11)) ((.) (showString "R ") (showsPrec 11 b1))
When typechecking a standalone-derived method for `Show (D t)':
showsPrec a (C b1)
= showParen ((a >= 11)) ((.) (showString "C ") (showsPrec 11 b1))
showsPrec a (R b1)
= showParen ((a >= 11)) ((.) (showString "R ") (showsPrec 11 b1))
It seems that one needs to be able to qualify over the existential type, saying something like "Show b => Show (D (Either a b))" for existential types b, or upgrad开发者_运维知识库e the implication "(Show a, Show b) => Show (Either a b)" so it is bidirectional.
Thanks very much!
(Please feel free to clean up the title or description.)
Add the Show
constraint to the existential,
data D t where
C :: t -> D t
R :: Show b => D b -> D (Either a b)
and you're in business.
Prelude> :r
[1 of 1] Compiling A ( A.hs, interpreted )
Ok, modules loaded: A.
*A> R (C 7)
R (C 7)
精彩评论