Reputation: 1328
I defined a custom GADT where the type constructor has a type class constraint on the type variable, like this:
data MyGadt x where
Sample :: Show a => a -> MyGadt a
Now, if I define the following two functions:
foo (Sample a) = show a
bar a = Sample a
GHC infers types for them that are a bit irritating to me.
foo :: MyGadt x -> [Char]
doesn't mention the Show
constraint for x
, while bar :: Show a => a -> MyGadt a
does require the constraint to be mentioned explicitly.
I was assuming that I don't have to mention the constraint because it is declared in the GADT definition.
The only thing I can think of being part of the reason is the position of the GADT in the function. I'm not super deep into that but as far as I understand it, MyGadt
is in positive position in foo
and in negative position in bar
.
When do I have to mention the type class constraints explicitly, and when does GHC figure it out itself based on the constraint on the GADTs type constructor?
Upvotes: 3
Views: 435
Reputation: 120711
It's the whole point of using a GADT that you want the constraint to show up in the signature of bar
, instead of foo
. If you don't want that, then you can use a plain old newtype
instead:
newtype MyAdt = Sample a
foo :: Show a => MyAdt a -> String
foo (Sample a) = show a
bar :: a -> MyAdt a
bar = Sample
Having the constraint in neither foo
nor bar
clearly can't work, because then you would be able to e.g.
showFunction :: (Integer -> Integer) -> String
showFunction = foo . bar
Upvotes: 3