The list monad's bind
It can map, filter, and locally transform a list
The word monad can be seen as scary, but you don't particularly need to worry about what it means in the general case in order to use the implementations of >>=
(bind). For example, the list monad, where >>=
is defined as below.
(>>=) :: [a] -> (a -> [a]) -> [a]
xs >>= k = join (fmap k xs)
When evaluating >>=
, each element of xs
is passed to k
, which returns a list, and then the lists from each invocation of k
are concatanated back together for the final value. This means that >>=
can be used as an alternative to filter
, map
, or be used for local transformations of the list, such as repeating each element.
As a filter
Often you would like to filter a list based on a predicate. This can be done with >>=
as below.
filtered = list >>= \x -> if predicate x then [x] else []
This is equivalent to the below use of filter
.
filtered = filter predicate list
As a map
>>=
can also be used to map a function over the elements of a list, i.e. end up with a list of the same length, but each element has been passed through another function. An example of this is below.
mapped = list >>= return . mapper
This is equivalent to just using map
.
mapped = map mapper list
As a local transform
The cases where >>>=
shines are those that can't be achieved using a single higher-order function. For example, repeating each element twice in a list.
repeated = list >>= \x -> [x, x]
Should I use >>=
?
My instinct is to use the least general code that solves the problem you're tackling, and solves it clearly. So while using >>=
for when there isn't a single other function that can do the job is good, using it when map
or filter
would do, while interesting, I would probably avoid.
Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.
Ian Malcom, Jurassic Park