[Haskell-cafe] mtl: Why there is "Monoid w" constraint in the definition of class MonadWriter?

Roman Cheplyaka roma at ro-che.info
Sun Dec 9 09:57:52 CET 2012


* Edward Z. Yang <ezyang at MIT.EDU> [2012-12-08 15:45:54-0800]
> > Second, even *if* the above holds (two tells are equivalent to one
> > tell), then there is *some* function f such that
> > 
> >     tell w1 >> tell w2 == tell (f w1 w2)
> > 
> > It isn't necessary that f coincides with mappend, or even that the type
> > w is declared as a Monoid at all. The only thing we can tell from the
> > Monad laws is that that function f should be associative.
> 
> Well, the function is associative: that's half of the way there to
> a monoid; all you need is the identity!  But we have those too:
> whatever the value of the execWriter (return ()) is...

Let me repeat:

  It isn't necessary that f coincides with mappend, or even that the
  type w is declared as a Monoid at all.

Let me illustrate this with an example.

  data MyWriter a = MyWriter Integer a

  instance Monad MyWriter where
    return = MyWriter 0
    MyWriter n x >>= k =
      let MyWriter n' y = k x
      in MyWriter (n+n') y

  instance MonadWriter Integer MyWriter where
    tell n = MyWriter n ()
    listen (MyWriter n x) = return (x,n)
    pass (MyWriter n (a,f)) = MyWriter (f n) a

Yes, integers do form a monoid when equipped with 0 and (+). However, we
know well why they are not an instance of Monoid — namely, there's more
than one way they form a monoid.

Even if something is in theory a monoid, there may be technical reasons
not to declare it a Monoid. Likewise, imposing a (technical) superclass
constraint on MonadWriter has nothing to do with whether the Monad will
be well-behaved.

This is true in both directions: even if the type is an instance of
Monoid, nothing forces the Monad instance to use the Monoid instance.
I.e. I can declare a MonadWriter on the Sum newtype whose bind, instead
of adding, subtracts the numbers.

Roman



More information about the Haskell-Cafe mailing list