eigenslur
Working notes · February 2026

CategoricalProbability

Probability Maps as First-Class Arrows

A sensor feeds a filter feeds a controller, and every handoff is a distribution. Markov kernels make each step a composable arrow, and Wasserstein distance measures how far apart two beliefs really sit.

§0The Big Idea

A sensor hands a noisy estimate to a filter, the filter hands a belief to a controller, and every handoff along the way is a distribution rather than a value.

The pipeline begs to be treated like function composition, and it can be: each stochastic step is a Markov kernel — an arrow X → Dist(Y) you compose like any other — and distributions carry a principled distance, Wasserstein, so “how far apart are these two beliefs?” has an actual answer. That buys clean plumbing for stochastic systems and a robust way to compare what a model expects against what a sensor reports.

§1Three Foundational Concepts

Giry Monad

A monad on measurable spaces sending each space X to the space of probability measures on X. The unit turns a point into a point mass; multiplication flattens a distribution over distributions into one distribution. Its Kleisli category has Markov kernels as morphisms — stochastic programs you can compose.

Markov Categories

A diagrammatic axiomatization of probability in which conditioning, disintegration, and conditional independence become algebraic laws — general enough that results like the Kolmogorov zero–one law admit purely diagrammatic proofs.

Kantorovich Monad

On complete metric spaces, the probability monad carries the Wasserstein distance, and the whole structure is generated by finite samples: distributions arise as limits of empirical ones. The bridge between sampling code and measure theory.

§2Why This Matters Practically

Compositional Pipelines

Model your system as Sensors → Latent State → Controller using arrows X → Dist(Y). Compose kernels instead of juggling PDFs. In the sheaf-fusion picture of the companion note, these kernels are the plumbing that connects local beliefs to transport costs.

Robustness Knobs

Penalize Wasserstein (W₁/W₂) between predicted and observed belief states. Fuse models by minimizing distance to the set or mixture you trust. The same move shows up in robust MPC, ensemble fusion, and distributional RL.

Sample ↔ Measure Sanity

The Kantorovich monad justifies treating batches as measures (and vice versa), so your empirical code matches the math: empirical distributions converge to the underlying measure in Wasserstein distance, and the limit your code approximates is the object the theory manipulates.

§3Runnable Example: Compare Beliefs

A minimal example showing how to compute the Wasserstein distance between two belief snapshots. Use this number to regularize a controller (e.g., add λ·W₁ to your cost) or to gate model switching.

belief_distance.py
python
import numpy as np
from scipy.stats import wasserstein_distance

# Two belief snapshots, each a bag of samples
a = np.array([0.1, 0.2, 0.2, 0.8])
b = np.array([0.15, 0.25, 0.7])

# Compute Wasserstein-1 distance
w1 = wasserstein_distance(a, b)
print("W1 =", w1)  # lower = closer beliefs

# Use in a controller cost function
# (the helpers below come from your own stack)
def augmented_cost(state, action, lambda_reg=0.1):
    base_cost = compute_base_cost(state, action)
    predicted_belief = predict_belief(state, action)
    observed_belief = get_observation()

    # Robustness penalty
    belief_mismatch = wasserstein_distance(
        predicted_belief,
        observed_belief
    )

    return base_cost + lambda_reg * belief_mismatch

§3.1Kernel Composition Pattern

Build stochastic pipelines by composing Markov kernels. Each arrow transforms distributions through a stochastic step.

kernel_composition.py
python
class MarkovKernel:
    """A stochastic map X -> Dist(Y)"""

    def __init__(self, transition_fn):
        self.transition = transition_fn

    def __call__(self, x):
        """Apply kernel to a point, get distribution"""
        return self.transition(x)

    def pushforward(self, dist_x):
        """Apply kernel to a distribution (bind)"""
        return flatten([self(x) for x in dist_x.samples])

    def compose(self, other):
        """Kleisli composition: (f >=> g)(x) = bind(f(x), g)"""
        def composed(x):
            intermediate = self(x)
            return other.pushforward(intermediate)
        return MarkovKernel(composed)

# Build a sensor-state-controller pipeline
sensor_to_latent = MarkovKernel(sensor_model)
latent_to_action = MarkovKernel(policy)

# Compose into end-to-end pipeline
sensor_to_action = sensor_to_latent.compose(latent_to_action)

§4Minimal Mental Model

  • Unit: Wrap a value into a degenerate distribution (Dirac delta). This is how deterministic values enter the stochastic world.
  • Map / Pushforward: Transform a distribution through a deterministic function. If f: X → Y and μ is a distribution on X, the pushforward f#μ is a distribution on Y: sample from μ, then apply f.
  • Bind (>>=): Run a stochastic step that returns a new distribution, then flatten. This is kernel composition — the essential plumbing operation.

§4.1Connection to Sheaf Fusion

Alongside the sheaf-fusion picture in the companion note on topos-theoretic probability, categorical probability supplies:

  • Clean glue between local beliefs, via kernel composition
  • Transport costs via built-in Wasserstein metrics
  • Structural reasoning — conditional independence expressed as an algebraic law in a Markov category

§5Further Reading

1

Giry (1982), A Categorical Approach to Probability Theory

The paper that made distributions a monad, with Markov kernels as the morphisms of its Kleisli category.

2

Fritz (2020), A Synthetic Approach to Markov Kernels

Markov categories in full: algebraic laws for conditioning, disintegration, and conditional independence, with classical theorems reproved diagrammatically.

3

Fritz & Perrone (2019), A Probability Monad as the Colimit of Spaces of Finite Samples

The Kantorovich monad: Wasserstein structure generated by finite empirical distributions.