# Specifying Kinds of Types

**RijkJ.C.vanHaaften
**
RijkJ.C.vanHaaften

*Fri, 08 Feb 2002 12:39:30 +0100*

Ashley Yakeley wrote:
>*I'd like to be able to declare the kinds of new types and synonyms,
*>*because sometimes Haskell can't infer them. For instance:
*>*
*>* data CMap0 p q = MkCMap0;
*>*
*>*Without evidence, Haskell assumes that p and q have kind '*' (as per sec.
*>*4.6), and therefore CMap0 has kind '* -> * -> *'. Actually, I wanted p
*>*and q to both have kind '* -> *', giving CMap0 kind '(* -> *) -> (* -> *)
*>*-> *'.
*...
>*It's not currently possible to specify kinds, is it?
*
It is possible using a trick due to John Hughes. In
Proceedings of the 1999 Haskell Workshop,
he wrote in his article
Restricted Data Types in Haskell
this note:
3 There is one unpleasant hack in the figure: The constructor Unused
in the
data type definition for Set. It is there purely in order to force the
compiler
to assign the parameter cxt the correct kind: without it, cxt does not
appear
at all in the right hand side of the definition, and is therefore
assigned the
(incorrect) kind *. The application cxt a forces the correct kind * ->
* to be
assigned, and embedding it in the type cxt a -> () prevents the type
of the
context from interfering with the derivation of a Show instance.
The figure mentioned contains
data Set cxt a = Set [a] | Unused (cxt a -> ()) deriving Show
You can follow the example of John, writing
data CMap0 p q = MkCMap0 | Unused (p a -> ()) (q a -> ());
(I think I'm correctly applying the trick, but other
Proceedings-readers will correct me if I'm wrong.)
As John writes, this is a hack, but we have no
other choice.
Rijk-Jan van Haaften