IDiscreteDistribution<T> abstracts a finite discrete probability distribution over values of type T. It inherits Sample(), then adds Support() to enumerate possible values and Weight(T) to assign each value a non-normalized integer weight. section 12.4
The interface makes three details explicit:
- Sampling returns a randomly selected T according to the distribution's weights. section 12.4
- Support() enumerates the values that may be sampled, while Weight(T) returns zero for values outside that support. section 12.4
- A value's probability equals its weight divided by the total support weight, avoiding the rounding issues of summing floating-point probabilities. section 12.4
A uniform die as an implementation
DiscreteUniform.Distribution(6) wraps Random while exposing the common distribution interface. Sample() produces a die result, Support() enumerates 0 through 5, and Weight(t) returns 1 for an in-range value and 0 otherwise. The abstraction is useful even when the first implementation is only a thin wrapper. section 12.4
Once distributions share this shape, they can compose. A prior distribution and a conditional distribution form a joint distribution; filtering and projecting that joint distribution produce a posterior. The same operations also supply Bind, Map, and Join for treating probability distributions as a monad. section 13.3 section 14.1
Listing 12.1 An interface and the discrete uniform distribution
public interface IDistribution<T>
{
T Sample();
}
public interface IDiscreteDistribution<T> : IDistribution<T>
{
IEnumerable<T> Support();
int Weight(T t);
}
public sealed class DiscreteUniform : IDiscreteDistribution<int>
{
private readonly Random rnd = new();
private readonly int max;
public static DiscreteUniform Distribution(int max)
{
if (max <= 0)
throw new InvalidOperationException();
return new(max);
}
private DiscreteUniform(int max) => this.max = max;
public int Sample() => rnd.Next(max);
public IEnumerable<int> Support() => Enumerable.Range(0, max);
public int Weight(int t) => 0 <= t && t < max ? 1 : 0;
}
The interface and uniform-distribution listing shows the contract, validation, sampling, support enumeration, and weight calculation together. section 12.4
