14 Third abstract nonsense interlude: The probability monad
The chapter extends the book’s category-theory-inspired view of generic types by showing that a discrete probability distribution type can be treated as a monad. In this framework, ordinary workflows over values can be lifted to workflows over random values, with a unit operation that wraps a single value and a bind operation that threads probabilistic computations together. The core idea is that probability distributions can be manipulated as structured objects rather than by direct calls to random-number APIs.
To make that concrete, the text defines a discrete distribution interface and shows how bind can be implemented by forming a joint distribution from a prior and a likelihood function, then projecting away the variable that is no longer needed. This supports Bayesian-style reasoning, such as combining a prior probability of having a cold with a likelihood of sneezing to obtain a marginal distribution over sneezing outcomes. The chapter also explains that monads imply map and join operations, and demonstrates join by flattening a distribution that produces other distributions, like a coin flip selecting between different dice.
The chapter then argues that discrete distributions also qualify as additive monads: they can be combined, they have an additive zero representing impossibility, and binding zero stays zero. That makes filtering possible in the usual monadic style, even though the presented version is less efficient than the earlier specialized approach. The final reflection is more skeptical: while the abstraction is elegant and useful for principled inference, integer weights and joint-distribution construction create performance and expressiveness limits, and the approach does not handle infinite discrete distributions.
Summary
- The discrete distribution type meets the requirements of a monad. We can create a
Unitwrapper around a single value, and we can implementBind. - Our implementation of
Bindinterprets the monad passed in as a prior and the function passed in as a likelihood. - If we want to, we can make the discrete distribution type an additive monad by creating an empty distribution, in which everything is impossible, and make a few small changes to the existing code.
- The tools we’ve developed are a big improvement over methods using
Random. We can build software that manipulates finite categorical distributions using principled, accurate Bayesian reasoning. But this is only a tiny part of the world of statistical programming.
FAQ
What is the main idea of this chapter?
The chapter shows that the discrete probability distribution type can be treated as a monad, so workflows that operate on ordinary values can also be used to operate on random values.
What are the three key requirements for a monad described in the chapter?
A monad should add a new capability through a generic type, provide a unit operation to wrap a value, and provide a bind operation to attach a new function to an existing workflow.
How does IDiscreteDistribution<T> add a new capability?
It can generate as many random values of type T as needed, according to a specific probability mass function.
What does Singleton<T>.Distribution(T) represent in the probability distribution monad?
It is the unit operation of the monad: it creates a wrapper distribution that remembers a single value.
How is Bind implemented for discrete distributions?
Bind is built by creating a joint distribution with ToJoint and then projecting out the second item with Project.
What is the role of a likelihood function in this chapter’s examples?
The likelihood function describes the distribution of an outcome given a prior value, such as the probability of sneezing given whether someone has a cold.
What is the result of binding the sneezing likelihood to a 10% prior on having a cold?
The resulting marginal distribution of sneezes is No:887 and Yes:113, corresponding to the right margin of the joint distribution table.
What are Map and Join in the context of monads?
Map applies a function to wrapped values, and Join flattens a distribution of distributions into a single distribution.
Why is the probability distribution type considered an additive monad?
Because distributions can be added together by merging supports and weights, there is an additive identity called MZero, and binding MZero always yields MZero.
What are the main criticisms or limitations of this probability monad approach?
It uses integer weights instead of fractional ones, joint distributions can become large and expensive to compute, and the approach does not handle infinite discrete distributions.
Fabulous Adventures in Data Structures and Algorithms ebook for free