views:

1604

answers:

1
+34  Q: 

Haskell Weird Kinds

When I was experimenting with Haskell kinds, and trying to get the kind of ->, and this showed up:

$ ghci
...
Prelude> :k (->)
(->) :: ?? -> ? -> *
Prelude> 

Instead of the expected * -> * -> *. What are the ?? and ? things? Do they mean concrete types or "kind variables"? Or something else?

+56  A: 

These are GHC-specific extensions of the Haskell kind system. The Haskell 98 report specifies only a simple kind system:

... type expressions are classified into different kinds, which take one of two possible forms:

The symbol * represents the kind of all nullary type constructors. If k1 and k2 are kinds, then k1->k2 is the kind of types that take a type of kind k1 and return a type of kind k2.

GHC extends this system with a form of kind subtyping, to allow unboxed types, and to allow the function construtor to be polymorphic over kinds. The kind lattice GHC supports is:

             ?
             /\
            /  \
          ??   (#)
          / \     
         *   #     

Where:       *   [LiftedTypeKind]   means boxed type
             #   [UnliftedTypeKind] means unboxed type
            (#)  [UbxTupleKind]     means unboxed tuple
            ??   [ArgTypeKind]      is the lub of {*, #}
            ?    [OpenTypeKind]     means any type at all

Defined in ghc/compiler/types/Type.lhs

In particular:

> error :: forall a:?. String -> a
> (->)  :: ?? -> ? -> *
> (\\(x::t) -> ...)

Where in the last example t :: ?? (i.e. is not an unboxed tuple). So, to quote GHC, "there is a little subtyping at the kind level".

For interested souls, GHC also supports coercion types and kinds ("type-level terms which act as evidence for type equalities", as needed by System Fc) used in GADTs, newtypes and type families.

Don Stewart
Terrifying. +1!
Norman Ramsey
Exciting as this all is - are there any cases where a user (as opposed to a compiler implementer) might care about / need to explicitly take advantage of these boxed/unboxed kind distinctions?At a superficial glance they seem like a bit of an abstraction leak of some internal inference mechanism used for optimisation within the compiler?
Matt
You'll care if you try to write functions that use types of kind other than '*' -- as they have various restrictions on how you can compose.
Don Stewart