Cast :: (Castable ab) => Expr a -> Expr b
So here:
instance (Show a) => Show (Expr a) where show (Cast e) = "Cast " ++ show e
Cast e is of type Expr a . We have a restriction of Show a , and it is this instance that implies Show (Expr a) , so we can call show for things like Expr a .
But e not of type Expr a . Cast takes an argument of any type Expr a1 and gives you Expr a (renaming type variables to stay consistent with what we say in the instance), so e is of type Expr a1 . We do not have a show restriction for type a1 , and we require Show a1 mean Show (Expr a1) , so there is no way to show e .
And there is no way to add such a restriction to the show instance, because type a1 not displayed in type Cast e . It seems like you should use GADT here; you intentionally threw away all the information about the type of thing Cast was applied to (except that Castable a1 a ), and declared the result simply Expr a .
source share