I am going through the Haskell wiki books GADTS
https://en.wikibooks.org/wiki/Haskell/GADT guide.
I was tracking pretty well until a Kind signature was added which generalizes the constrained type of the Cons constructor.
data Safe
data NotSafe
data MarkedList :: * -> * -> * where
Nil :: MarkedList t NotSafe
Cons :: a -> MarkedList a b -> MarkedList a c
safeHead :: MarkedList a Safe -> a
safeHead (Cons x _) = x
silly 0 = Nil
silly 1 = Cons () Nil
silly n = Cons () $ silly (n-1)
With the Kind Signature I can use the Cons constructor to construct and pattern match against both Safe and Unsafe MarkedLists. While I understand what going on I am unfortunately having trouble building any intuition as to how the Kind Signature is allowing this. Why do I need the Kind Signature? What is the Kind Signature doing?
The same way a type signature works for values, a kind signature works for types.
Here,
ftakes two argument values and produces a result value. The equivalent for types could be:The type
Dtakes two argument types and produces a result type (it is* -> * -> *). For example,D Int Stringis a type (which has kind*). The partial applicationD Inthas kind* -> *, just the same way the partial applicationf 15has typeInt -> Bool.So we could rewrite the above as:
In GHCi, you can query types and kinds: