7.8. Kind polymorphism
Prev | Chapter 7. GHC Language Features | Next

## 7.8. Kind polymorphism

This section describes kind polymorphism, and extension enabled by `-XPolyKinds`. It is described in more detail in the paper Giving Haskell a Promotion, which appeared at TLDI 2012.

### 7.8.1. Overview of kind polymorphism

Currently there is a lot of code duplication in the way Typeable is implemented (Section 7.5.3, “Deriving clause for extra classes (`Typeable`, `Data`, etc)”):

    class Typeable (t :: *) where
      typeOf :: t -> TypeRep

    class Typeable1 (t :: * -> *) where
      typeOf1 :: t a -> TypeRep

    class Typeable2 (t :: * -> * -> *) where
      typeOf2 :: t a b -> TypeRep

Kind polymorphism (with `-XPolyKinds`) allows us to merge all these classes into one:

    data Proxy t = Proxy

    class Typeable t where
      typeOf :: Proxy t -> TypeRep

    instance Typeable Int  where typeOf _ = TypeRep
    instance Typeable []   where typeOf _ = TypeRep

Note that the datatype `Proxy` has kind `forall k. k -> *` (inferred by GHC), and the new `Typeable` class has kind `forall k. k -> Constraint`.

### 7.8.2. Overview

Generally speaking, with `-XPolyKinds`, GHC will infer a polymorphic kind for un-decorated declarations, whenever possible. For example:

    data T m a = MkT (m a)
    -- GHC infers kind   T :: forall k. (k -> *) -> k -> *

Just as in the world of terms, you can restrict polymorphism using a kind signature (sometimes called a kind annotation) (`-XPolyKinds` implies `-XKindSignatures`):

    data T m (a :: *) = MkT (m a)
    -- GHC now infers kind   T :: (* -> *) -> * -> *

There is no "forall" for kind variables. Instead, when binding a type variable, you can simply mention a kind variable in a kind annotation for that type-variable binding, thus:

    data T (m :: k -> *) a = MkT (m a)
    -- GHC now infers kind   T :: forall k. (k -> *) -> k -> *

The kind "forall" is placed just outside the outermost type-variable binding whose kind annotation mentions the kind variable. For example

    f1 :: (forall a m. m a -> Int) -> Int
             -- f1 :: forall (k:BOX).
             --       (forall (a:k) (m:k->*). m a -> Int)
             --       -> Int

    f2 :: (forall (a::k) m. m a -> Int) -> Int
             -- f2 :: (forall (k:BOX) (a:k) (m:k->*). m a -> Int)
             --       -> Int

Here in `f1` there is no kind annotation mentioning the polymorphic kind variable, so `k` is generalised at the top level of the signature for `f1`, making the signature for `f1` is as polymorphic as possible. But in the case of of `f2` we give a kind annotation in the `forall (a:k)` binding, and GHC therefore puts the kind `forall` right there too.

(Note: These rules are a bit indirect and clumsy. Perhaps GHC should allow explicit kind quantification. But the implicit quantification (e.g. in the declaration for data type T above) is certainly very convenient, and it is not clear what the syntax for explicit quantification should be.)

### 7.8.3. Polymorphic kind recursion and complete kind signatures

Just as in type inference, kind inference for recursive types can only use monomorphic recursion. Consider this (contrived) example:

    data T m a = MkT (m a) (T Maybe (m a))
    -- GHC infers kind  T :: (* -> *) -> * -> *

The recursive use of `T` forced the second argument to have kind `*`. However, just as in type inference, you can achieve polymorphic recursion by giving a complete kind signature for `T`. The way to give a complete kind signature for a data type is to use a GADT-style declaration with an explicit kind signature thus:

    data T :: (k -> *) -> k -> * where
      MkT :: m a -> T Maybe (m a) -> T m a

The complete user-supplied kind signature specifies the polymorphic kind for `T`, and this signature is used for all the calls to `T` including the recursive ones. In particular, the recursive use of `T` is at kind `*`.

What exactly is considered to be a "complete user-supplied kind signature" for a type constructor? These are the forms:

- A GADT-style data type declaration, with an explicit "`::`" in the header. For example:

      data T1 :: (k -> *) -> k -> *       where ...   -- Yes  T1 :: forall k. (k->*) -> k -> *
      data T2 (a :: k -> *) :: k -> *     where ...   -- Yes  T2 :: forall k. (k->*) -> k -> *
      data T3 (a :: k -> *) (b :: k) :: * where ...   -- Yes  T3 :: forall k. (k->*) -> k -> *
      data T4 a (b :: k)             :: * where ...   -- YES  T4 :: forall k. * -> k -> *

      data T5 a b                         where ...   -- NO  kind is inferred
      data T4 (a :: k -> *) (b :: k)      where ...   -- NO  kind is inferred

  It makes no difference where you put the "`::`" but it must be there. You cannot give a complete kind signature using a Haskell-98-style data type declaration; you must use GADT syntax.

- An open type or data family declaration always has a complete user-specified kind signature; no "`::`" is required:

      data family D1 a           	-- D1 :: * -> *
      data family D2 (a :: k)    	-- D2 :: forall k. k -> *
      data family D3 (a :: k) :: *    -- D3 :: forall k. k -> *
      type family S1 a :: k -> *      -- S1 :: forall k. * -> k -> *

      class C a where                 -- C  :: k -> Constraint
        type AT a b                   -- AT :: k -> * -> *

  In the last example, the variable `a` has an implicit kind variable annotation from the class declaration. It keeps its polymorphic kind in the associated type declaration. The variable `b`, however, gets defaulted to `*`.

In a complete user-specified kind signature, any un-decorated type variable to the left of the "`::`" is considered to have kind "`*`". If you want kind polymorphism, specify a kind variable.

### 7.8.4. Kind inference in closed type families

Although all open type families are considered to have a complete user-specified kind signature, we can relax this condition for closed type families, where we have equations on which to perform kind inference. GHC will infer a kind for any type variable in a closed type family when that kind is never used in pattern-matching. If you want a kind variable to be used in pattern-matching, you must declare it explicitly.

Here are some examples (assuming `-XDataKinds` is enabled):

    type family Not a where      -- Not :: Bool -> Bool
      Not False = True
      Not True  = False

    type family F a where        -- ERROR: requires pattern-matching on a kind variable
      F Int   = Bool
      F Maybe = Char

    type family G (a :: k) where -- G :: k -> *
      G Int   = Bool
      G Maybe = Char

    type family SafeHead where   -- SafeHead :: [k] -> Maybe k
      SafeHead '[] = Nothing     -- note that k is not required for pattern-matching
      SafeHead (h ': t) = Just h

### 7.8.5. Kind inference in class instance declarations

Consider the following example of a poly-kinded class and an instance for it:

    class C a where
      type F a

    instance C b where
      type F b = b -> b

In the class declaration, nothing constrains the kind of the type `a`, so it becomes a poly-kinded type variable `(a :: k)`. Yet, in the instance declaration, the right-hand side of the associated type instance `b -> b` says that `b` must be of kind `*`. GHC could theoretically propagate this information back into the instance head, and make that instance declaration apply only to type of kind `*`, as opposed to types of any kind. However, GHC does not do this.

In short: GHC does not propagate kind information from the members of a class instance declaration into the instance declaration head.

This lack of kind inference is simply an engineering problem within GHC, but getting it to work would make a substantial change to the inference infrastructure, and it's not clear the payoff is worth it. If you want to restrict `b`'s kind in the instance above, just use a kind signature in the instance head.

Prev | Up | Next
7.7. Type families | Home | 7.9. Datatype promotion