[Haskell-cafe] mapM_ -> Monoid.Monad.map

Derek Elkins derek.a.elkins at gmail.com
Fri Jan 23 18:06:08 EST 2009


On Fri, 2009-01-23 at 13:39 -0800, George Pollard wrote:
> On Fri, 2009-01-23 at 21:30 +0000, Joachim Breitner wrote:
> > Hi,
> > 
> > Am Freitag, den 23.01.2009, 21:50 +0100 schrieb Henning Thielemann:
> > >   However our recent Monoid discussion made me think about mapM_, 
> > > sequence_, and friends. I think they could be useful for many monads if
> 
> > > they would have the type:
> > >   mapM_ :: (Monoid b) => (a -> m b) -> [a] -> m b
> > >    I expect that the Monoid instance of () would yield the same
> efficiency 
> > > as todays mapM_
> > 
> > will it? This is based on a naive, not well-founded understanding of
> > haskell evaluation, but looking at
> > > instance Monoid () where
> > >	mempty        = ()
> > >	_ `mappend` _ = ()
> > >	mconcat _     = ()
> > I’d assume that evaluating
> > > mapM_ (putStrLn) lotsOfLargeStrings
> > with your proposed mapM_ will leave a thunk equivalent to
> > > () `mappend` () `mappend` () `mappend`...
> > in memory until the mapM_ has completely finished, where each () is
> > actually an unevalutated thunk that still has a reference to one of the
> > elements in the lotsOfLargeStrings list.
> 
> Perhaps this is why the Monoid instance for () in GHC's source has the
> comment "should this be strict?" :)

It's easy to calculate the answer.

mempty `mappend` undefined = undefined (left identity monoid law)
The above definition doesn't meet this, similarly for the right identity
monoid law.  That only leaves one definition, () `mappend` () = () which
does indeed satisfy the monoid laws.

So the answer to the question is "Yes."  Another example of making
things as lazy as possible going astray.



More information about the Haskell-Cafe mailing list