

Rather than the stuff left of the => being special purpose syntax fairly disconnected from the rest of the language, now what is acceptable there is anything with kind Constraint. (* -> k) -> k.ĬonstraintKinds makes constraints (the stuff to the left of the => in type signatures, like Eq a) become ordinary type-level entities in a new kind: Constraint. PolyKinds adds kind variables that work exactly the same way type variables work.

There are several language extensions that add more features to the kind language. data ThreeStars a b = Cons a b makes a type constructor with kind * -> * -> *, while data AlsoThreeStars f = AlsoCons (f Integer) makes a type constructor with kind (* -> *) -> *. For example * -> * -> * is the kind of things that take two type arguments to produce a type, but (* -> *) -> * is the kind of things that take a single argumemt to produce a type where that argument itself must be a thing that takes a type argument to produce a type. It's not just the number of * or -> that matter, but how they are nested.

The most basic form of the kind language contains only * (or Type in more modern Haskell I suspect we'll eventually move away from *) and ->.īut there are more things you can build with that language than you can express by just "counting the number of *s".
