Reputation: 186
I'm playing with GADTs and explicit forall on ghc 7.8.2. Let's look at the following simple example:
{-# LANGUAGE GADTs, RankNTypes #-}
data T1 a where
T1 :: (b -> a) -> b -> T1 a
data T2 a where
T2 :: forall b. (b -> a) -> b -> T2 a
Here ghc fails with:
Test.hs:7:26: Not in scope: type variable ‘a’
Test.hs:7:35: Not in scope: type variable ‘a’
When T2
is commented out type checking succeeds.
But T1
and T2
are seemingly equivalent. Is this a bug in ghc or some limitation of GADTs? If the latter then what is the difference between the two?
Upvotes: 3
Views: 160
Reputation: 38227
I was struggling with a similar problem. Based on chi's comment, I came up with this solution:
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
data T2 :: * -> * where
T2 :: forall a b. (b -> a) -> b -> T2 a
I would rather have preferred the b
to stand out in comparison to the a
, but I guess this is still better than an implicit forall
for those who prefer it explicit, which includes myself.
Upvotes: 0
Reputation: 186
I originally assumed that a
in T1
constructor was binded at data T1 a
declaration.
But it actually is implicitly quantified in a constructor itself. Therefore T2
constructor is wrong because it explicitly quantifies b
and doesn't quantify a
.
Upvotes: 4