[Haskell-cafe] Stacking monads

Ryan Ingram ryani.spam at gmail.com
Fri Oct 3 15:40:46 EDT 2008


On Fri, Oct 3, 2008 at 12:10 PM, Andrew Coppin
<andrewcoppin at btinternet.com> wrote:
> Again, it looks like MonadPlus == Monad + Monoid, except all the method
> names are different. Why do we have this confusing duplication?

MonadPlus is a class for type constructors, generic over the type of
the elements:

class MonadPlus m where
    mzero :: m a
    mplus :: m a -> m a -> m a

(note the lack of "a" in the class signature; the methods have to be
defined for ALL possible "a").

whereas monoid is a class for concrete types:

class Monoid a where
    mempty :: a
    mappend :: a -> a -> a

The MonadPlus instance for lists is very constrained:

instance MonadPlus [] where
    mzero = [] -- only possibly definition
    mplus = (++)

There's no other possible fully-defined definition of mzero, and the
laws for mplus constrain its definition significantly; the only real
change you are allowed to make is to merge the elements of the two
input lists in some interesting fashion.  Even then you need to keep
the relative ordering of the elements within a list the same.

The monoid definition is far more open, however; there are many
possible monoid definitions for lists.  This admits a definition like
the following:

instance Monoid a => Monoid [a] where
    mempty = [mempty]
    mappend xs ys = [x `mappend` y | x <- xs, y <- ys]

Of course, other definitions are possible; this one fits the monoid laws:
   mempty `mappend` a == a
   a `mappend` mempty == a
but there are other choices that do so as well (one based on zipWith,
for example, , or drop the "Monoid a" constraint and just use [] and
++)

It's similar to Monad vs. Applicative; you can use any Monad
definition to create a valid Applicative definition, but it's possible
that other definitions exist, or, at the least, are more efficient.

  -- ryan


More information about the Haskell-Cafe mailing list