looking for data structure advice
Conor McBride
c.t.mcbride at durham.ac.uk
Wed Dec 24 13:27:34 EST 2003
Hi
Sorry to take so long: I've spent a week watching paint dry, so I can
confirm that this is more interesting.
Jon Cast wrote:
>
> Conor McBride <c.t.mcbride at durham.ac.uk> wrote:
> <snip>
>
> > I've always been a little bothered by the MonadPlus class: zero and
> > plus are associated (no pun intended) in my mind with monoidal
> > structure. Is there more to MonadPlus than a clumsy workaround for
> > the lack of quantified constraints?
>
> Yes. For every functor m with a MonadPlus instance, m () has /two/
> monoids, (mzero, mplus) and (return (), (>>)). MonadPlus is thus no
> more a workaround than the category Field; MonadPlus is simply a way to
> specify that a functor has two monoid-like structures, one more exact
> than the other, together with the expectation that the two monoids are
> related in a manner similar to the relationship of the two
> (more-or-less-) groups that make up a field.
That's a fair point. As these fieldy things are two monoids plus
distributive laws, they deserve special recognition. Do they have a name
(semirings, or something?).
Generally speaking, (return (), (>>)) seems to be just one instance of
the fact that if m is a monad and x is a monoid wrt (zero, plus), say,
then (m x) is also a monoid wrt (return zero, liftM2 plus). It's the
ability to push application under m (with appropriate laws) which
makes this possible: monads are just one structure which allows this
to happen.
A non-monadic example: [IO Int] has
{zero = [], plus = (++),
one = return (return 0), times = liftM2 (liftM2 (+))}
with distributive laws etc, but ([] . IO) is not monadic.
> > If we could have quantified constraints, e.g.
> >
> > (Monad m, forall x. Monoid (m x))
> >
> > wouldn't that be better than having Monad-specific monoids?
>
> No. Consider the monad Writer (IO ()). The Writer monad wants a Monoid
> instance, and the most natural such instance is often (return (), (>>)).
> OTOH, this monad is always wrong in the cases where, currently, you
> would use mplus. So you can't just replace MonadPlus with Monoid; you
> need to be more specific about your choice of monoid than can be
> accounted for by a single class.
>
> <snip>
This is basically an unfortunate consequence of some design choices in
the class system, rather than a good thing per se. Pragmatically, it's
really annoying, at least to me, that I can't classify both of these
monoid structures as monoids, in order to use monoid-generic operators
(e.g. flattening) on either. I can't help thinking that newtype offers
a better workaround than making the monoidal aspect of MonadPlus not a
Monoid. But I would prefer to have some way to be more specific about
choice of monoid (indeed of instance, generally) in some localized way.
Merry Christmas
Conor
More information about the Haskell-Cafe
mailing list