Maybe
is not a type. Maybe Int
is a type. But Maybe
, on its own, is something you can make a type out of. It is a type constructor function.
Either
is not a type, it is a type constructor. You know how you can curry Haskell functions? Well, you can curry type constructor functions too. So Either
is a 2-argument type constructor function, but Either Int
is a 1-argument type constructor. And Either Int Bool
is an actual type.
The Functor
type-class is a higher-kinded type-class. Something like Show
applies to a type; Functor
applies to a type constructor. For example, you do not write
instance Functor (Maybe Int) where ...
Instead, you write
instance Functor (Maybe) where ...
The definition of Functor
is
class Functor f where
fmap :: (x -> y) -> f x -> f y
Here f
is not a type, but a 1-argument type constructor function. You give it an argument (such as x
or y
) to construct a real, usable type.
Values have "types". Things in a type signature have "kinds". A "type" has kind *
. A "1-argument type constructor" has kind "* -> *". It basically says how many arguments you have to supply to get an actual type.
In summary, you could write an instance for Functor (Either Int)
. But then only Int
would be allowed; by making it a type variable, you make it more polymorphic.
Notice that if you wanted it so that the second argument to Either
was fixed rather than the first one... you can't do that. In a sense, higher-kinded type-classes are a bit of a kludge. It they're simple to understand and they work for the easy cases. Functional Dependencies and Associated Types are two (incompatible) attempts to solve this problem better.