Maybe
We discussed that the Reader r monad isn't actually a new type at all. It is
simply a type alias for ReaderT r Identity. It equips the identity monad,
which represents pure functions, with some context of type r.
As far as the behaviour of the Maybe monad is concerned, we could define
Maybe in the same way, as
type Maybe = MaybeT Identity
However, Maybe is a data type that has its uses simply as a type to represent
the presence or absence of a value. For example, if we have a program that we
can run with or without a file name as argument, we could have a data type
representing the command line arguments of the program like this one:
data Args = Args
{
...
fileName :: Maybe String
...
}
In this case, Nothing does not represent failure, and we're not interested in
the fact that Maybe is also a monad. That's why Maybe is a concrete type and
not an alias for MaybeT Identity.
The consequence is that we need two separate Monad instances for Maybe and
MaybeT m, which implement the same logic. We didn't have to do this for
Reader r because Reader r is really only useful as a monad, so it was fine
to define it as an alias for ReaderT r Identity, and let Reader r become a
monad by virtue of ReaderT r Identity being one.