Haskell/Understanding monads/List

From Wikibooks, the open-content textbooks collection

Jump to: navigation, search
The List ([]) monad


Similarly to how Maybe represents a result that might or might not have a well defined value, lists can be thought as representing a result whose number of elements is left unspecified.

TODO:

  • Example: isGrandparent = not . null . (children >=> children)
  • relation to Maybe
  • nondeterminism

[edit] Instantiation as Monad

Lists are basic elements in Haskell, and you have surely used them extensively before getting to this chapter. The implementation of the return function, that injects a generic value into a list, is quite simple:

return x = [x]

In other words, injecting a value into a list means making a list containing that value only.

The binding operator is less trivial. Its type for the case of lists should be:

[a] -> (a -> [b]) -> [b]

Meaning, from a list of a-type values and a function producing lists of b-type values from each a-type one, we get a list of b's. The final list of b's is the concatenation of all those produced by the function by each of the a's; this is to say, the concatenation of the list of lists we obtain by mapping the function on the original list of a's:

xs >>= f = concat (map f xs)

[edit] Example: Bunny Invasion

A rabbit couple can spawn six rabbits every month. Considering half of them will be females, we can model the number of female rabbits after a certain number of generations using a function like:

> let generation = replicate 3
> ["bunny"] >>= generation
["bunny","bunny","bunny"]
> ["bunny"] >>= generation >>= generation
["bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny"]

In this trivial example all elements are equal, but one could for example model radioactive decay or chemical reactions, or any phenomena that produces a series of elements starting from a single one.