Reader small image

You're reading from  Functional Python Programming, 3rd edition - Third Edition

Product typeBook
Published inDec 2022
PublisherPackt
ISBN-139781803232577
Edition3rd Edition
Right arrow
Author (1)
Steven F. Lott
Steven F. Lott
author image
Steven F. Lott

Steven Lott has been programming since computers were large, expensive, and rare. Working for decades in high tech has given him exposure to a lot of ideas and techniques, some bad, but most are helpful to others. Since the 1990s, Steven has been engaged with Python, crafting an array of indispensable tools and applications. His profound expertise has led him to contribute significantly to Packt Publishing, penning notable titles like "Mastering Object-Oriented," "The Modern Python Cookbook," and "Functional Python Programming." A self-proclaimed technomad, Steven's unconventional lifestyle sees him residing on a boat, often anchored along the vibrant east coast of the US. He tries to live by the words “Don't come home until you have a story.”
Read more about Steven F. Lott

Right arrow

 13
The PyMonad Library

A monad allows us to impose an order on an expression evaluation in an otherwise lenient language. We can use a monad to insist that an expression such as a + b + c is evaluated in left-to-right order. This can interfere with the compiler’s ability to optimize expression evaluation. This is necessary, however, when we want files to have their content read or written in a specific order: a monad is a way to assure that the read() and write() functions are evaluated in a particular order.

Languages that are lenient and have optimizing compilers benefit from monads imposing order on the evaluation of expressions. Python, for the most part, is strict and does not optimize, meaning there are few practical requirements for monads in Python.

While the PyMonad package contains a variety of monads and other functional tools, much of the package was designed to help folks understand functional programming using Python syntax. We’ll...

13.1 Downloading and installing

The PyMonad package is available on the Python Package Index (PyPI). In order to add PyMonad to your environment, you’ll need to use the python -m pip pymonad command to install it.

This book used version 2.4.0 to test all of the examples. Visit https://pypi.python.org/pypi/PyMonad for more information.

Once the PyMonad package is installed, you can confirm it using the following commands:

>>> import pymonad 
>>> help(pymonad)

This will display the module’s docstring and confirm that things really are properly installed.

The overall project name, PyMonad, uses mixed case. The installed Python package name that we import, pymonad, is all lower case.

13.2 Functional composition and currying

Some functional languages work by transforming a multi-argument function syntax into a collection of single argument functions. This process is called currying: it’s named after logician Haskell Curry, who developed the theory from earlier concepts. We’ve looked at currying in depth in Chapter 11, The Toolz Package. We’ll revisit it from the PyMonad perspective here.

Currying is a technique for transforming a multi-argument function into higher-order single argument functions. In a simple case, consider a function f(x,y) z; given two arguments x and y; this will return some resulting value, z. We can curry the function f(x,y) into into two functions: fc1(x) fc2(y) and fc2(y) z. Given the first argument value, x, evaluating the function fc1(x) returns a new one-argument function, fc2(y). This second function can be given the second argument value, y, and it returns the desired result, z.

We can...

13.3 Functors – making everything a function

The idea of a functor is a functional representation of a piece of simple data. A functor version of the number 3.14 is a function of zero arguments that returns this value. Consider the following example:

>>> pi = lambda: 3.14 
>>> pi() 
3.14

We created a zero-argument lambda object that returns a Python float object.

When we apply a curried function to a functor, we’re creating a new curried functor. This generalizes the idea of applying a function to an argument to get a value by using functions to represent the arguments, the values, and the functions themselves.

Once everything in our program is a function, then all processing becomes a variation on the theme of functional composition. To recover the underlying Python object, we can use the value attribute of a functor object to get a Python-friendly, simple type that we can use in uncurried code.

Since this kind of programming is based on...

13.4 Monad bind() function

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 order.

Python, as we have seen, is already strict. It doesn’t require monads. We can, however, still apply the concept in places where it can help clarify a complex algorithm. We’ll look at an example, below, of using a monad-based approach to designing a simulation based on Markov chains.

The technology for imposing strict evaluation is a binding between a monad and a function that will return a monad. A flat expression will become nested bindings that can’t be reordered by an optimizing compiler. The then() method of a monad imposes this strict ordering.

In other languages, such as Haskell, a monad...

13.5 Implementing simulation with monads

Monads are expected to pass through a kind of pipeline: a monad will be passed as an argument to a function and a similar monad will be returned as the value of the function. The functions must be designed to accept and return similar structures.

We’ll look at a monad-based pipeline that can be used for simulation of a process. This kind of simulation is sometimes called a Monte Carlo simulation. In this case, the simulation will create a Markov chain.

A Markov chain is a model for a series of potential events. The probability of each event depends only on the state attained in the previous event. Each state of the overall system had a set of probabilities that define the events and related state changes. It fits well with games that involve random chance, like dice or cards. It also fits well with industrial processes where small random effects can ”ripple through” the system, leading to effects that may not appear to be...

13.6 Additional PyMonad features

One of the other features of PyMonad is the confusingly named monoid. This comes directly from mathematics and it refers to a group of data elements that have an operator and an identity element, and the group is closed with respect to that operator. Here’s an example of what this means: when we think of natural numbers, the add operator, and an identity element 0, this is a proper monoid. For positive integers, with an operator *, and an identity value of 1, we also have a monoid; strings using + as an operator and an empty string as an identity element also qualify.

PyMonad includes a number of predefined monoid classes. We can extend this to add our own monoid class. The intent is to limit a compiler to certain kinds of optimization. We can also use the monoid class to create data structures which accumulate a complex value, perhaps including a history of previous operations.

The pymonad.list is an example of a monoid. The identity element is...

13.7 Summary

In this chapter, we looked at how we can use the PyMonad library to express some functional programming concepts directly in Python. The module contains many important functional programming techniques.

We looked at the idea of currying, a function that allows combinations of arguments to be applied to create new functions. Currying a function also allows us to use functional composition to create more complex functions from simpler pieces. We looked at functors that wrap simple data objects to make them into functions that can also be used with functional composition.

Monads are a way to impose a strict evaluation order when working with an optimizing compiler and lazy evaluation rules. In Python, we don’t have a good use case for monads because Python is an imperative programming language under the hood. In some cases, imperative Python may be more expressive and succinct than a monad construction.

In the next chapter, we’ll look at the multiprocessing and...

13.8 Exercises

This chapter’s exercises are based on code available from Packt Publishing on GitHub. See https://github.com/PacktPublishing/Functional-Python-Programming-3rd-Edition.

In some cases, the reader will notice that the code provided on GitHub includes partial solutions to some of the exercises. These serve as hints, allowing the reader to explore alternative solutions.

In many cases, exercises will need unit test cases to confirm they actually solve the problem. They are often identical to the unit test cases provided in the GitHub repository. The reader should replace the book’s example function name with their own solution to confirm that it works.

13.8.1 Revise the arctangent series

In Using the lazy ListMonad() monad, we showed a computation for π that involved summing fractions from a series that used factorials, n!, and double factorials, (2n + 1)!!.

The examples use a sequence seq1 = ListMonad(*range(20)) with only 20 values. This choice...

Join our community Discord space

Join our Python Discord workspace to discuss and know more about the book: https://packt.link/dHrHU

PIC

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Functional Python Programming, 3rd edition - Third Edition
Published in: Dec 2022Publisher: PacktISBN-13: 9781803232577
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at ₹800/month. Cancel anytime

Author (1)

author image
Steven F. Lott

Steven Lott has been programming since computers were large, expensive, and rare. Working for decades in high tech has given him exposure to a lot of ideas and techniques, some bad, but most are helpful to others. Since the 1990s, Steven has been engaged with Python, crafting an array of indispensable tools and applications. His profound expertise has led him to contribute significantly to Packt Publishing, penning notable titles like "Mastering Object-Oriented," "The Modern Python Cookbook," and "Functional Python Programming." A self-proclaimed technomad, Steven's unconventional lifestyle sees him residing on a boat, often anchored along the vibrant east coast of the US. He tries to live by the words “Don't come home until you have a story.”
Read more about Steven F. Lott