In Haskell the "types" of types are called Kinds, denoted as *
. Such as in:
This is not correct. *
is the kind of types, i.e. of such type-level entities which represent a set† of possible runtime values.
The term kind is a bit of a cludge. It's only needed because Haskell (for good reasons, no less!) has a clear distinction between compile time and run time. Values only exist at runtime, everything else only exists at compile time. In particular, the type of such values only exists at compile time.
Now, it's desirable to classify types as well, just as it is desirable to classify values in types. In principle, there is no reason not to consider types just like any other value and thus have types of types. This is pretty much the foundational idea of dependently-typed languages like Idris or Agda¶.
In Haskell this doesn't quite work: because of the aforementioned runtime/compiletime distinction you can't throw types and values in one closed‡ pot. Thus the concept of kinds: these are also types, but types of things that, unlike values, also exist at compile time like the kinds themselves do, not at runtime like values.
This means that there's no need to go yet another level up from kinds, because there's no earlier level than compile-time. (Unless you bring Template Haskell in the game; no idea if anybody has considered such issues yet.)
†They aren't really sets, but kind of (pun not intended).
‡Closed in the sense: you can talk about types of types of types of... and never really need to invent anything new.
¶I understand that Agda still makes a distinction between types, type-types etc. (Set_2
and so on). But I believe this has more to do with the fact that Agda is a total language. I could be wrong here, though.
Set_2
but why stop there?)