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 
     to assign the parameter cxt the correct kind: without it, cxt does not 
     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