[Haskell-cafe] Re: The danger of Monad ((->) r)

Conal Elliott conal at conal.net
Fri May 25 13:53:23 EDT 2007


Oops -- I wasn't watching this thread.  I like Jules's definition, though
I'd write it as follows.

-- Standard instance: monad applied to monoid
instance Monoid a => Monoid (IO a) where
  mempty  = return mempty
  mappend = liftM2 mappend

You can replace "IO" with any monad at all, to make similar instances.

Here's the instance i use.  It's in Control.Instances in the TypeCompose
library.  See http://www.haskell.org/haskellwiki/TypeCompose.

-- Standard instance: applicative functor applied to monoid
instance Monoid a => Monoid (IO a) where
  mempty  = pure mempty
  mappend = (*>)

On second thought, I don't really like (*>), since it's easy to accidentally
discard a useful value.  (I dislike (>>) for the same reason.)  Generalizing
the "monad applied to monoid" instance above:

-- Standard instance: applicative functor applied to monoid
instance Monoid a => Monoid (IO a) where
  mempty  = pure mempty
  mappend = liftA2 mappend

That will be the definition in the next TypeCompose release.

All of these instances agree for a = ().  The first & third are more
compelling to me than the second, since they make full use of the Monoid a
constraint.

Cheers,  - Conal

On 5/16/07, Jules Bean <jules at jellybean.co.uk> wrote:
>
> Tomasz Zielonka wrote:
> > On Wed, May 16, 2007 at 09:28:31AM +0100, Jules Bean wrote:
> >
> >> Tomasz Zielonka wrote:
> >>
> >>> You mean using the (Monoid b) => Monoid (a -> b) instance ?
> >>> I can see that IO () makes a perfect Monoid, but there doesn't seem to
> >>> be a standard instance for that.
> >>>
> >> Indeed, all Monads are Monoids (that is, if m :: * -> * is a Monad,
> then
> >> m a :: * is a Monoid, for any fixed type a) by using >>.
> >>
> >
> > Are you sure that (IO Int) is a monoid with mappend = (>>)? How do you
> > define mempty, so it is an identity for mappend?
> >
> > It would help if type a was a Monoid, then:
> >
> >     mempty = return mempty
> >     mappend mx my = do
> >         x <- mx
> >         y <- my
> >         return (x `mappend` y)
> >
> > It's easier if a = ().
> >
>
> Oops, you're right. I spoke too fast.
>
> It's only a monoid for (). Otherwise you can't hope to have a right
> identity.
>
> Jules
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20070525/01ec47b7/attachment.htm


More information about the Haskell-Cafe mailing list