In opposition of Functor as super-class of Monad

Ben Millwood haskell at
Thu Oct 25 17:04:16 CEST 2012

The major advantage that I see of making Applicative a superclass of
Monad is actually not anywhere to do with the data types or instances,
but rather to do with functions that operate on the class. For
example, the liftM* family of functions becomes entirely redundant,
and can be eliminated in favour of liftA*, which reduces the number of
arbitrary choices we need to make and understand. As another example,
we sometimes want to use functions (like void or fmap) that work with
Functor and functions (like join) that need Monad in the same
(polymorphic) code. We then have to state *both* constraints in the
context for the code, despite the fact that if one is satisfied, the
other must surely be. For example, defining instance Functor (StateT s
m) you have to choose whether to use the context (Monad m) or (Functor
m): the latter is more general, but requires your programs that use
fmap *and* bind to specify (Monad m, Functor m), and the former is
almost always what's used in practice anyway. This tension just
doesn't exist if one is a superclass of the other.

Some code will break, yes, but I think most people would agree that
the presence of a Monad instance with no corresponding Applicative
instance is a bug anyway, and should be fixed.

(Note that if Applicative and Monad are both defined for the same
type, it is required by the Applicative docs that return = pure and
<*> = ap, at least extensionally. Of course the implementation can be
cleverer, but if you want it to be actually /different/ in behaviour,
please use a newtype).

More information about the Haskell-prime mailing list