Recall a couple of type classes we have seen:
class Eq t where
(==) :: t -> t -> Bool
(/=) :: t -> t -> Bool
class Foldable t where
foldr :: (a -> b -> b) -> b -> t a -> b
Notice that the types t
in the Foldable
class are applied to other types (i.e. t a
).
The types t
in Eq
are different types of types than those in Foldable
.
The "type of a type" is called a kind in Haskell.
Proper types, or ground types or monotypes, are described with kind *
(pronounced "star").
> :kind Int
> :k Int
> :k (Int, Int)
> :k Int -> Int
> :k Int -> Int -> Int
Type constructors, or type functions or type operators, are described with arrow kinds.
> :k Maybe
> :k []
> :k (,)
> :k (,,)
> :k (->)
A "fully applied" type is a proper type or a type constructor applied to enough arguments to produce a proper type. Only proper types are "inhabited" by Haskell values.
Kinds are not written in type class definitions, but it's helpful to think about them explicitly (like forall
quantifiers in polymorphic types). The KindSignatures
flag allows them to be written.
{-# LANGUAGE KindSignatures #-}
class Eq (t :: *) where
...
class Foldable (t :: * -> *) where
...