Specifying Kinds of Types

Zhanyong Wan zhanyong.wan@yale.edu
Mon, 11 Feb 2002 11:44:59 -0500


Hi Ashley,

If you don't want to build ghc, or would rather use hugs, here's a (dirty)
trick which John Hughes used in his "restricted data types" paper (I hope I
recall correctly) to specify kinds.

For your first example, you can write:

data CMap0 p q = MkCMap0
        | CMap0_Unused (p Int) (q Int)

The idea is that you never use the CMap0_Unused branch, but it tells
Haskell that p and q have kind * -> *.  Your code would become less
efficient if what you had was a newtype.

For your second example, you have to turn it into a data declaration:

data Composer c = Composer (forall x y z. (c y z) -> (c x y) -> (c x z))
  | Composer_Unused (c [] [])

Of course, you cannot insist on Composer being a type synonym any more.  Is
this solution acceptable to you?

- Zhanyong Wan

Simon Peyton-Jones wrote:

> OK, it's done.  In GHC you can specify kinds in
> [...]
>
>
> And you can put kind signatures on arbitrary types, rather
> like you can put type signatures on arbitrary expressions.
>
> No kind polymorphism though!
>
> All this is in the HEAD.  You'll need to build from source to get it
> until we make a release.

> | 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 '(* -> *)
> | -> (* -> *)
> | -> *'.
> |
> | Here's another example:
> |
> |     type Composer c = forall x y z. (c y z) -> (c x y) -> (c x z);
> |
> | Haskell gives x, y and z all the kind '*'. But I wanted them
> | to have kind
> | '* -> *', giving c the kind '(* -> *) -> (* -> *) -> *' and
> | Composer the
> | kind '(* -> *) -> (* -> *) -> * -> *'.