The PyMonad Library
We can now map the / operator to the map() and operator.truediv parallel
functors:
2*sum(map(operator.truediv, f1, f2))
3.1415919276751456
The map() function will apply the given operator to both functors, yielding a
sequence of fractions that we can add.
The f1 & f2 method will create all combinations of values from the two
List objects. This is an important feature of List objects: they readily
enumerate all combinations allowing a simple algorithm to compute
all alternatives and filter the alternatives for the proper subset. This is
something we don't want; that's why we used the map() function instead
of the operator.truediv * f1 & f2 method.
We defined a fairly complex calculation using a few functional composition techniques
and a functor class definition. Here's the full definition for this calculation:
(^0) ()
!
2
n 2 1!!
n
n
π
∞
= ∑= +
Ideally, we prefer not to use a fixed sized List object. We'd prefer to have a lazy and
potentially infinite sequence of integer values. We could then use a curried version
of sum() and takewhile() functions to find the sum of values in the sequence
until the values are too small to contribute to the result. This would require an even
lazier version of the List() object that could work with the itertools.counter()
function. We don't have this potentially infinite list in PyMonad 1.3; we're limited to
a fixed sized List() object.
Monad concepts, the bind() function
and the Binary Right Shift operator
The name of the PyMonad library comes from the functional programming concept
of a monad, a function that has a strict order. The underlying assumption behind
much functional programming is that functional evaluation is liberal: it can be
optimized or rearranged as necessary. A monad provides an exception that imposes
a strict left-to-right ordering.