I've run into an odd situation in GHC 8.0.1 with kind-indexed (?) GADTs where introducing foralls in the type vs kind signatures produces different type-checking behaviors.
Consider the following data types:
{-# LANGUAGE TypeInType, GADTs, ExplicitForAll #-}
-- Same thing happens when we replace ExplicitForAll with ScopedTypeVariables
import Data.Kind
data F (k :: * -> *) where
data G :: F k -> * where
G :: G x
This data type compiles just fine. However, if we want to specify the kind of x
in the constructor G
, we get a type error.
data H :: F k -> * where
H :: forall k' (x :: F k'). H x
The error message is
• Kind variable ‘k’ is implicitly bound in datatype ‘H’, but does not appear as the kind of any of its type variables. Perhaps you meant to bind it (with TypeInType) explicitly somewhere? • In the data declaration for ‘H’
If we add the forall
to the kind signature (with or without the forall
in the constructor), there is no error.
data I :: forall k. F k -> * where
I :: I x
data J :: forall k. F k -> * where
J :: forall k' (x :: F k'). J x
What's going on?
F k
to be fixed for the whole declaration, while the latter allowsH
to be used in its own declaration at different kinds. I.e. it allows polykinded recursion. Could be similar to the "parameters vs indices" distinction in inductive types (as in Agda/Coq). – chik
in the constructor:data H' :: F k -> * where H' :: forall (x :: F k). H' x
produces the same error asH
. And second, because my understanding is that GHC doesn't have a parameter/index distinction, not even with TypeInType :-) – Antal Spector-Zabusky