Ertugrul Soeylemez es at ertes.de
Tue Feb 9 21:41:20 EST 2010

```Patrick LeBoutillier <patrick.leboutillier at gmail.com> wrote:

> > Sure. If you don't mind that the mutations come in a different
> > order, one thing that works wonders is "sequence",
> >
> > sequence :: Monad m => [m a] -> m [a]
> >
> > In particular, for m = [], sequence :: [[a]] -> [[a]]. Then, knowing what
> > sequence does, we can write
> >
> >
> > generateAll :: String -> [String]
> > generateAll word = sequence (map f word)
> >     where
> >     f c = case lookup c leat of
> >                Just r  -> [c,r]
> >                Nothing -> [c]
>
> That's very nice!
>
> One question though: In the docs sequence is described as:
>
>   "Evaluate each action in the sequence from left to right, and
> collect the results."
>
> How is one supposed to deduce what the behavior will be for the list
> monad (besides looking at the source)?

Intuitively it's very easy to understand and makes perfect sense, if you
interpret the list monad as nondeterminism:

sequence [c1,c2,c3] = do
x1 <- c1
x2 <- c2
x3 <- c3
return [x1,x2,x3]

sequence ["ab", "cd", "ef"] = do
x1 <- "ab"
x2 <- "cd"
x3 <- "ef"
return [x1,x2,x3]

In this code x1 stands for all results of c1, x2 for all results of c2
and x3 for all results of c3.  It's a convenient way of doing list
which have interesting behaviours in the list monad.

Greets
Ertugrul

--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/

```