If I inspect the kind of Maybe I get this:
λ> :k Maybe
Maybe :: * -> *
Now, if I inspect the kind of Monad I get this:
λ> :k Monad
Monad :: (* -> *) -> Constraint
What is Constraint there and why it is needed ? Why not just this * -> * ?
Unlike
Maybe,Monadis not a type; it is a typeclass.The same goes for other typeclasses:
Where
*represents concrete types (such asBoolorInt),->represent higher-kinded types (such asMaybe), andConstraintrepresents the idea of a type constraint. This is why:As we know we can't make a signature like this:
Because
Monadshould be used as a constraint, to say that, 'this must be a monad to work':We do this because we know that
returncan't work on any old typem, so we define the behaviour ofreturnfor different types under the nameMonad. In other words, there is no single thing that can be called a Monad, but only behaviour that can be called Monadic.For this reason, we have created this type constraint, saying that we must have pre-defined something as a Monad to use this function. This is why the kind of
Monadis(* -> *) -> Constraint- it itself is not a type!Maybeis an instance ofMonad. This means that somewhere, someone has written:...and defined how
Maybeshould behave as a Monad. This is why we can useMaybewith functions or types that have the prefix constraintMonad m => .... This is essentially where one defines the constraint applied byMonad.