Donn Cave donn at drizzle.com
Thu Dec 22 12:28:51 EST 2005

```On Thu, 22 Dec 2005, Paul Moore wrote:
...
> FWIW, I don't really see why the -M functions are needed either. It's
> something to do with the fact that map is for lists, and mapM is for
> monads, which are a more general type of sequence than a list. But why
> mapM isn't therefore a superset of map, and so map is redundant, I
> don't know.

This reminds me why I like Hugs - whether I normally use it or not,
I have it installed so that I can refer to lib/Prelude.hs, my single

You can offer any number of conceptual explanations of these things,
but there seems to be no way to guarantee that they're going to be
taken the right way.  The Prelude definitions may or may not make
sense, but at worst I don't think they can muddy the issue.

I'm also reminded that there we're talking about several distinctly
different types of learning here.  If you're taking a class, you
might well profit from a structured sequence that focuses on the
static declarative aspects first, avoids recursion, etc.  If you're
on your own - as commonly the case with people reading tutorials -
it's important to present the language in a useful form as soon as
possible, let there be a temptation to switch to the Objective CAML
tutorial because of a mistaken impression.

Donn Cave, donn at drizzle.com
-------
sequence       :: Monad m => [m a] -> m [a]
sequence []     = return []
sequence (c:cs) = do x  <- c
xs <- sequence cs
return (x:xs)

sequence_        :: Monad m => [m a] -> m ()
sequence_         = foldr (>>) (return ())

mapM             :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f            = sequence . map f

mapM_            :: Monad m => (a -> m b) -> [a] -> m ()
mapM_ f           = sequence_ . map f

```