My (possibly mildly tortured) reading of chapter 4 of the Haskell 2010 Report is that Maybe
and (->) r
are both types, of kind * -> *
. Alternatively, the Report also labels them as type expressions—but I can't discern a firm difference in how the Report uses the two terms, except perhaps for surface syntax details. (->)
and Maybe
are type constructors; type expressions are assembled from type constructors and type variables.
For example, section 4.1.1 ("Kinds") of the 2010 report says (my boldface):
To ensure that they are valid, 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 κ1 and κ2 are kinds, then κ1 → κ2 is the kind of types that take a type of kind κ1 and return a type of kind κ2.
Section 4.3.2, "Instance Declarations" (my boldface):
An instance
declaration that makes the type T to be an instance of class C is called a C-T instance declaration and is subject to these static restrictions:
- A type may not be declared as an instance of a particular class more than once in the program.
- The class and type must have the same kind; this can be determined using kind inference as described in Section 4.6.
So going by that language, the following instance
declaration makes the type (->) r
to be an instance of the class Functor
:
instance Functor ((->) r) where
fmap f g = f . g
The funny thing about this terminology is that we call (->) r
a "type" even though there are no expressions in Haskell that have that type—not even undefined
:
foo :: (->) r
foo = undefined
{-
[1 of 1] Compiling Main ( ../src/scratch.hs, interpreted )
../src/scratch.hs:1:8:
Expecting one more argument to `(->) r'
In the type signature for `foo': foo :: (->) r
-}
But I think that's not a big deal. Basically, all declarations in Haskell must have types of kind *
.
As a side note, from my limited understanding of dependently typed languages, many of these lack Haskell's firm distinction between terms and types, so that something like (->) Boolean
is an expression whose value is a function that takes a type as its argument and produces a type as its result.