| 1 | == Kind Parameters and Overloading On Kinds == |

| 2 | |

| 3 | We start by defining a ''kind'', which is useful for passing kinds as parameters. |

| 4 | {{{ |

| 5 | data OfKind (a :: *) = KindParam |

| 6 | }}} |

| 7 | Note that we are only interested in the promoted version of this datatype, |

| 8 | so basically we just defined a singe type constant with a polymorphic kind: |

| 9 | {{{ |

| 10 | KindParam :: OfKind k |

| 11 | }}} |

| 12 | |

| 13 | In addition, it is also convenient to define the following type synonym: |

| 14 | {{{ |

| 15 | type KindOf (a :: k) = (KindParam :: OfKind k) |

| 16 | }}} |

| 17 | |

| 18 | This makes it easy to write kind parameters in terms of existing types. |

| 19 | Here are some examples: |

| 20 | {{{ |

| 21 | KindOf Int ~ (KindParam :: OfKind *) |

| 22 | KindOf 1 ~ (KindParam :: OfKind Nat) |

| 23 | KindOf "Hi" ~ (KindParam :: OfKind Symbol) |

| 24 | }}} |

| 25 | |