FunctorApplicativeMonad Proposal
From HaskellWiki
The standard class hierarchy is a consequence of Haskell's historical development, rather than logic.
This article attempts to document various suggestions that have been brought up over the years, along with arguments for and against.
Contents
 1 Make Applicative a superclass of Monad
 2 Add join as a method of Monad
 3 Remove liftM, ap, etc. in favor of their Applicative counterparts
 4 Split fail into its own class
 5 Rename fmap to map
 6 Export Applicative in the Prelude
 7 Redefine >> in terms of *> rather than >>=
 8 Add a Pointed class
 9 Related proposals
Make Applicative
a superclass of Monad
class Applicative m => Monad m where
...
For
 Code that is polymorphic over the Monad can use Applicative operators rather than the ugly
liftM
andap
.
 Most types that implement Monad also implement Applicative already. This change will only make explicit a current best practice.
Against
 Monad is part of standard Haskell, but Applicative is not. If Monad is made a subclass of Applicative, then we will need to add Applicative to the language standard.
 Some libraries, such as blazemarkup, only implement Monad for its donotation. For these types, an Applicative instance would have no meaning.
Add join
as a method of Monad
class Applicative m => Monad m where
(>>=) :: (a > m b) > m a > m b
join :: m (m a) > m a
...
m >>= k = join (fmap k m)
join m = m >>= id
For

fmap
/join
is more orthogonal, and is closer to the categorical definition.

join
is often easier to implement. See [1].
 The analogous comonad package is written this way.
Against

>>=
is used much more frequently in realworld code thanjoin
.
 Performance: The default implementation of
>>=
requires two traversals. A containerlike type which only implementsjoin
would most likely be slower.
Remove liftM
, ap
, etc. in favor of their Applicative counterparts
For
 We will end up with a simpler base library.
Against
 A lot of code will be broken by this change. Of course, we can gradually deprecate them as with
Prelude.catch
.
 A common pattern is to write a full instance of Monad, then set
fmap = liftM
and(<*>) = ap
. The functions are still useful for this purpose.
Split fail
into its own class
class Monad m => MonadFail m where
fail :: String > m a
Rename fmap
to map
class Functor f where
map :: (a > b) > f a > f b
Export Applicative
in the Prelude
Redefine >>
in terms of *>
rather than >>=
Add a Pointed
class
class Pointed p where
point :: a > p a
This is already implemented in the pointed package.
For
Against
 This class has seen little realworld use. On Hackage, there are only 9 reverse dependencies for
pointed
, most of which are by the same author.
Related proposals
 From early 2011: GHC ticket – Makes Applicative into a superclass of Monad, but does not deprecate any existing names
 See [2] for the associated discussion.
 The Other Prelude
Context alias would also be a great help with backwards compatibility. The class system extension proposal may also help.