This article is part of a series on functional programming.
In the article on the Failure monad we looked at a simple definition of what a monad is:
A monad is a design pattern that allows us to add a context to data values, and also allows us to easily compose existing functions so that they execute in a context aware manner.
In this article we will look at the List monad. This is a monad that allows us to process lists of values, without cluttering our code with looping constructs.
As with the Failure monad, our List monad should do three main things:
So a simple use might be like this:
k = List([1, 2, 3]) n = k.bind(neg) print(n) # List([-1, -2, -3])
We will call our monad
List because that is the name that is commonly used for similar monads in other languages. Notice that a
List monad is quite different to a normal Python
Based on the previous implementation of the Failure monad, here is our List monad:
class List(): def __init__(self, value): self.value = value def get(self): return self.value def bind(self, f): result = list(map(f, self.value)) return List(result) def __str__(self): return 'List(' + ', '.join(map(str, self.value)) + ')' def __or__(self, f): return self.bind(f)
The List monad just wraps a single value, which should be a list or other sequence. This is stored as
bind function uses
map to apply the supplied function
f to each element in
self.value. The resulting list is wrapped in a new List monad.
str to return 'List([contents of list])'. Finally we override the
| so we can use it as a bind operator.
If you found this article useful you might be interested in my ebook Functional Programming in Python.
Copyright (c) Axlesoft Ltd 2020