I've created a GADT for expressions. When I pattern match on constructors that have constraints, the typechecker is unable to deduce constraints on the type variables used in the constructor's constraints. I think the code and error message are more elucidating.
{-# LANGUAGE GADTs, MultiParamTypeClasses #-}
import Data.Word
data Expr a where
Value :: a -> Expr a
Cast :: (Castable a b) => Expr a -> Expr b
class Castable a b where
cast :: a -> b
instance Castable Word64 Word32 where
cast = fromIntegral
instance (Show a) => Show (Expr a) where
show (Cast e) = "Cast " ++ show e -- ERROR
The error I get:
gadt.hs:16:30:
Could not deduce (Show a1) arising from a use of `show'
from the context (Show a)
bound by the instance declaration at gadt.hs:15:10-34
or from (Castable a1 a)
bound by a pattern with constructor
Cast :: forall b a. Castable a b => Expr a -> Expr b,
in an equation for `show'
at gadt.hs:16:9-14
Possible fix:
add (Show a1) to the context of
the data constructor `Cast'
or the instance declaration
In the second argument of `(++)', namely `show e'
In the expression: "Cast " ++ show e
In an equation for `show': show (Cast e) = "Cast " ++ show e
Edit: If I comment out the Show (Expr a)
instance and add the following code, it works fine:
eval :: Expr a -> a
eval (Value a) = a
eval (Cast e) = cast $ eval e
main = do
let bigvalue = maxBound `div` 2 + 5 :: Word64
e = Cast (Value bigvalue) :: Expr Word32
v = eval e
putStrLn "typechecks."
print (bigvalue, v)
I would want the show instance to basically print something like Cast (Value bigvalue)
.
Cast
value is existential, so you don't know anything about, e.g. how to show it. Your current GADT is essentially equivalent to something likedata Expr a = Value a | Cast (Expr a)
. You could add aShow
constraint but I suspect that's a case of treating the symptom, and that what you should really do is take a step back and think about what you're trying to do in the first place. – shachafCast
constructor. – nitromaster101Cast :: (Castable b a) => Expr b -> Expr a
would probably have been enough for you to understand what the problem was. – augustss