## Print a list of arbitrary values

The function `map` would print out every value from the list, but would produce `[IO ()]`. We'd thus need to chain `sequence \$ map`, which is exactly how the function `mapM` is defined. Because we are not collecting the results of `print` but focus only on its actions, we can discard them with `mapM_`.

```printList :: Show a => [a] -> IO ()
printList = mapM_ print
```

## Generalize the bunny invasion example

If we were not working with monads, applying function `f :: a -> a` three times would be achieved by `f(f(f(x)))`, which can be rewritten as `(f . f . f) x`. This suggests that if we want to generalize it to apply the function `n` times we could fold the list of `f`s using the `(.)` as the accumulating function:

```composeTimes :: Int -> (a -> a) -> (a -> a)
composeTimes n f = foldr (.) id \$ replicate n f
```

The initial value for `foldr` is `id` since ${\displaystyle f^{0}(x)=x}$ .

Now all we have to do is translate this to monads, that is replace `(.)` with monad composition operator `(>=>)`, `id` with `return` and arbitrary `f` with `generation`, yielding:

```generations :: Int -> a -> [a]
generations n = foldr (>=>) return \$ replicate n generation
```

We can verify that it works as expected:

```Prelude> ["bunny"] >>= generations 0
["bunny"]
Prelude> ["bunny"] >>= generations 1
["bunny","bunny","bunny"]
Prelude> ["bunny"] >>= generations 2
["bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny"]
```

## What is the expected behavior of `sequence` for the `Maybe` monad?

The `Maybe` monad represents a possible failure. If a failure occurred at any point in computing a list then the whole list cannot be computed, thus we expect that `sequence` of a list will produce `Nothing` if there are `Nothing`s in the list and `Just` a list otherwise. This is indeed what happens:

```Prelude> sequence [Just 1, Just 2, Just 3]
Just [1,2,3]
Prelude> sequence [Just 1, Nothing, Just 3]
Nothing
```