The Giry monad on the category of measurable spaces sends to the space of probability measures on , with the -algebra generated by the evaluation maps . Its unit and multiplication are
and the Kleisli composite of and is the Chapman–Kolmogorov integral . The Kleisli Category is , the category of measurable spaces and Markov kernels — the prototypical Markov Category.
Sources: Giry, A categorical approach to probability theory, LNM 915 (1982); Lawvere (1962), The category of probabilistic mappings; Fritz arXiv:1908.07021 (notes) §4 (Lemma 4.1: is an affine symmetric monoidal monad; hence is Markov by Corollary 3.2); Cho & Jacobs arXiv:1709.00322 (notes) Example 2.5.
Why a monad, and why an affine commutative one
- Monad: a random variable whose law is itself random can be flattened by averaging; this is . Kleisli arrows are exactly “stochastic functions”.
- Commutative / symmetric monoidal: the product measure makes symmetric monoidal (Fubini is what makes the two ways of forming it agree). This is what lets independent kernels run in parallel.
- Affine: — there is exactly one probability measure on a point. This is naturality of deletion, i.e. normalisation. Dropping normalisation (s-finite or sub-probability kernels) keeps a monad but loses affineness, and the Kleisli category becomes a Copy-Discard Category rather than a Markov category.
Relatives
| monad | on | Kleisli category | Markov? |
|---|---|---|---|
| Giry | yes | ||
| finitely supported (Distribution Monad) | discrete Markov kernels | yes | |
| Radon monad | compact Hausdorff spaces | continuous kernels | yes (Fritz §5) |
| sub-probability / s-finite measures | no — only copy-discard | ||
| non-empty power set | possibilistic kernels | yes (Fritz Ex. 2.6) | |
| probability monad of Gaussians | — | yes; faithful into (Fritz Proposition 6.1) |
Probabilistic programming languages denote programs as Kleisli morphisms of such monads; sample, observe and return are Kleisli composition, conditioning and .
Docs: Theories (Catlab): copy/delete — ThMonoidalCategoryWithDiagonals
# The finite Giry/distribution monad with Dicts: η = Dirac, μ = averaging, Kleisli = Chapman–Kolmogorov.
η(x) = Dict(x => 1.0)
function μ(Π) # Π : distribution over distributions, as (ν => w) pairs
out = Dict{Any,Float64}()
for (ν, w) in Π, (x, p) in ν
out[x] = get(out, x, 0.0) + w * p
end
out
end
bind(ν, f) = μ([f(x) => p for (x, p) in ν]) # Kleisli extension
weather = Dict(:rain => 0.3, :dry => 0.7)
grass(w) = w == :rain ? Dict(:wet => 0.9, :dry => 0.1) : Dict(:wet => 0.2, :dry => 0.8)
wet = bind(weather, grass)
round(wet[:wet]; digits = 2) # 0.3·0.9 + 0.7·0.2 = 0.41
bind(weather, η) == weather # right unit law: true
sum(values(wet)) ≈ 1 # affine: normalisation is preservedimport Mathlib
open MeasureTheory
-- Mathlib's Giry monad lives on `Measure`; probability measures are the affine part.
#check @Measure.dirac -- η
#check @Measure.bind -- Kleisli extension μ ∘ G f
#check @Measure.join -- μ : Measure (Measure α) → Measure α
#check @Measure.bind_dirac -- a unit law
#check ProbabilityMeasure-- The finitely supported probability monad, i.e. the discrete Giry monad
newtype Dist a = Dist { runDist :: [(a, Double)] }
instance Functor Dist where fmap f (Dist xs) = Dist [ (f x, p) | (x, p) <- xs ]
instance Applicative Dist where
pure x = Dist [(x, 1)] -- η: the Dirac distribution
Dist fs <*> Dist xs = Dist [ (f x, p * q) | (f, p) <- fs, (x, q) <- xs ]
instance Monad Dist where
Dist xs >>= k = Dist [ (y, p * q) | (x, p) <- xs, (y, q) <- runDist (k x) ] -- μ: averaging
data W = Rain | Dry deriving (Eq, Show)
data G = Wet | Parched deriving (Eq, Show)
weather :: Dist W
weather = Dist [(Rain, 0.3), (Dry, 0.7)]
grass :: W -> Dist G
grass Rain = Dist [(Wet, 0.9), (Parched, 0.1)]
grass Dry = Dist [(Wet, 0.2), (Parched, 0.8)]
pWet :: Double
pWet = sum [ p | (Wet, p) <- runDist (weather >>= grass) ] -- 0.41