Join removes one level of nesting from a monad: it transforms M<M<T>> into M<T>. The usual construction binds the identity function, preserving the monad’s meaning while eliminating the redundant wrapper. section 11.3 section 11.5
Join sits beside the other fundamental monad operations:
- Unit wraps an ordinary value as M<T>. section 11.3
- Bind applies a monad-returning function while preserving the monad’s effects or capabilities. section 11.3
- Map applies an ordinary function; Join can be derived by binding the identity function. section 11.5
Flattening a choice of dice
A distribution that chooses between a six-sided die and a ten-sided die has type IDiscreteDistribution<IDiscreteDistribution<int>>. Calling Join produces one distribution of integers. Its weights are 1–6: 8 each and 7–10: 3 each, reflecting the two equally likely inner distributions. section 14.1
Flattening probabilistic workflows
A probability distribution can produce another distribution: flip a fair coin, then roll a six-sided die on tails or a ten-sided die on heads. Join converts that nested distribution into an equivalent unnested distribution. The same pattern supports marginalizing a sneezing distribution conditioned on a cold prior. section 14.1
public static IDiscreteDistribution<T> Join<T>(
this IDiscreteDistribution<IDiscreteDistribution<T>> deep) =>
deep.Bind(x => x);
The generic implementation makes the definition executable: Bind the nested distribution to the identity function. section 14.1


