I recommend you use StandaloneKindSignatures
:
..
{-# Language StandaloneKindSignatures #-}
type Id :: k -> k
type Id a = a
type Proxy :: k -> Type
data Proxy a = Proxy
type
PK :: k -> Type
type family
PK a where
PK Int = Char
The kind argument is invisible but you can write it explicitly in the type family PK @Type Int = Char
(requires TypeApplications
).
With GADTs you can write Proxy
type Proxy :: k -> Type
data Proxy a where
Proxy :: Proxy @k a
There are proposals to allow visible (kind) applications in the declaration heads:
type Id :: k -> k
type Id @k a = a
type Proxy :: k -> Type
data Proxy @k a = Proxy
type
PK :: k -> Type
type family
PK @k a where
PK @Type Int = Char
And we can use "visible dependent quantification" in kinds with forall->
instead of (implicit) invisible forall.
type Id :: forall k -> k -> k
type Id k a = a
type Proxy :: forall k -> k -> Type
data Proxy k a = Proxy
type
PK :: forall k -> k -> Type
type family
PK k a where
PK Type Int = Char
Difference between Proxy
, defined as a uniform datatype (non-GADT or tongue-in-cheek: 'legacy' syntax) or a GADT. They are equivalent (tested on an old GHC 8.10) apart from k being
- (
forall.
) specified = can be specified with TypeApplications
, but is automatically inferred if not specified
- (
forall{}.
) inferred = TypeApplications
skips it, cannot be specified directly
This applies both to the type constructor Proxy
and the data constructor named P
for disambiguation since both are polymorphic. Proxy
can be specified Proxy @Nat 42
or inferred Proxy 42
depending on the quantification of k
:
Proxy :: forall (k :: Type). k -> Type
-- or
Proxy :: forall {k :: Type}. k -> Type
And depending on the quantification in P
, k can be specified P @Nat @42
or inferred P @42
:
P :: forall {k :: Type} (a :: k). Proxy @k a
P :: forall {k :: Type} (a :: k). Proxy a
-- or
P :: forall (k :: Type) (a :: k). Proxy @k a
P :: forall (k :: Type) (a :: k). Proxy a
This gives several outcomes
- k inferred in both:
P @42 :: Proxy 42
(P @42 :: Proxy 42
)
data Proxy a = P
--
data Proxy a where
P :: Proxy a
- k specified in
Proxy
but inferred in P
(P @42 :: Proxy @Nat 42
)
data Proxy (a :: k) where
P :: Proxy a
--
type Proxy :: k -> Type
data Proxy a where
P :: Proxy a
- k specified in both
Proxy
and P
(P @Nat @42 :: Proxy @Nat 42
)
data Proxy (a :: k) = P
--
type Proxy :: k -> Type
data Proxy a = P
--
type Proxy :: forall k. k -> Type
data Proxy a = P
--
type Proxy :: forall k. k -> Type
data Proxy (a :: k) = P
--
type Proxy :: k -> Type
data Proxy a where
P :: Proxy @k a
I am waiting for the dust to settle on many of the new and coming changes to quantification and scoping, this may already be out of date.