- Kinds and some type-foo

Learn You a Haskell For Great Good says:

Types are little labels that values carry so that we can reason about the values. But types have their own little labels, called kinds. A kind is more or less the type of a type. … What are kinds and what are they good for? Well, let’s examine the kind of a type by using the :k command in GHCI.

Scala 2.10 didn’t have a `:k`

command, so I wrote kind.scala.
Thanks to George Leontiev (@folone) and others, `:kind`

command is now part of Scala 2.11 (scala/scala#2340). Let’s try using it:

```
scala> :k Int
scala.Int's kind is A
scala> :k -v Int
scala.Int's kind is A
*
This is a proper type.
```

`Int`

and every other types that you can make a value out of are called a proper type and denoted with a `*`

symbol (read “type”). This is analogous to the value `1`

at value-level. Using Scala’s type variable notation this could be written as `A`

.

```
scala> :k -v Option
scala.Option's kind is F[+A]
* -(+)-> *
This is a type constructor: a 1st-order-kinded type.
scala> :k -v Either
scala.util.Either's kind is F[+A1,+A2]
* -(+)-> * -(+)-> *
This is a type constructor: a 1st-order-kinded type.
```

These are normally called *type constructors*. Another way of looking at it is that it’s one step removed from a proper type. So we can call it a first-order-kinded type. This is analogous to a first-order value `(_: Int) + 3`

, which we would normally call a function at the value level.

The curried notation uses arrows like `* -> *`

and `* -> * -> *`

. Note, `Option[Int]`

is `*`

; `Option`

is `* -> *`

. Using Scala’s type variable notation they could be written as `F[+A]`

and `F[+A1,+A2]`

.

```
scala> :k -v Eq
algebra.Eq's kind is F[A]
* -> *
This is a type constructor: a 1st-order-kinded type.
```

Scala encodes (or complects) the notion of typeclasses using type constructors.
When looking at this, think of it as `Eq`

is a typeclass for `A`

, a proper type.
This should make sense because you would pass `Int`

into `Eq`

.

```
scala> :k -v Functor
cats.Functor's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
```

Again, Scala encodes typeclasses using type constructors,
so when looking at this, think of it as `Functor`

is a typeclass for `F[A]`

, a type constructor.
This should also make sense because you would pass `List`

into `Functor`

.

In other words, this is a type constructor that accepts another type constructor.
This is analogous to a higher-order function, and thus called *higher-kinded type*.
These are denoted as `(* -> *) -> *`

. Using Scala’s type variable notation this could be written as `X[F[A]]`

.

The terminology around typeclasses tends to get jumbled up.
For example, the pair `(Int, +)`

forms a typeclass called monoid.
Colloquially, we say things like “is *X* a monoid?” to mean “can *X* form a monoid under some operation?”

An example of this is `Either[A, B]`

, which we implied “is-a” functor yesterday.
This is not completely accurate because, even though it might not be useful, we *could have* defined another left-biased functor.

herding cats — Kinds and some type-foo