Trait rand_functors::RandomVariable
source · pub trait RandomVariable: Sizedwhere
Standard: Distribution<Self>,{
// Required method
fn sample_space() -> impl Iterator<Item = Self>;
}
Expand description
A type that is enumerable and can be sampled from uniformly.
This trait requires that an implementor also implement
Distribution<Self>
, to ensure that it can be sampled from. Additionally,
a sample_space
associated function must be provided.
Note that a non-uniform distribution or a non-exhaustive sample space will
result in a logic error. In particular, this means that this trait should
not be implemented for Option<T>
, as the probability of None
being sampled is 0.5, regardless of the cardinality of the sample space of
T
.
§Provided Implementations
This crate provides implementations of RandomVariable
for bool
and all
twelve built-in integer types.
Implementations are provided for u32
, u64
, u128
, usize
,
i32
, i64
, i128
, and isize
strictly for sampling from ranges
(through RandomStrategy::fmap_rand_range
). The use of
RandomStrategy::fmap_rand
with a 32-bit integer RandomVariable
would
involve, at minimum, a 4 GiB allocation just to enumerate the outcomes of a
random process. This is obviously intractable on current computers.
§Implementing RandomVariable
Neither Distribution<T> for Standard
nor RandomVariable for T
are
derivable. However, implementations for simple structs tends to follow a
pattern. Distribution<Self>
implementations will typically call
self.sample(rng)
for each field of the struct. RandomVariable
implementations will typically use Iterator::flat_map
to create a
Cartesian product of all the sample spaces of the struct’s fields.
use rand::distributions::Standard;
use rand::prelude::*;
use rand_functors::RandomVariable;
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct Coordinate {
x: u8,
y: u8,
}
impl Distribution<Coordinate> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Coordinate {
Coordinate {
x: self.sample(rng),
y: self.sample(rng),
}
}
}
impl RandomVariable for Coordinate {
fn sample_space() -> impl Iterator<Item = Self> {
u8::sample_space().flat_map(|x| u8::sample_space().map(move |y| Coordinate { x, y }))
}
}
Required Methods§
sourcefn sample_space() -> impl Iterator<Item = Self>
fn sample_space() -> impl Iterator<Item = Self>
Produce an Iterator
containing all possible values of this type.
This iterator must be finite, though a trait bound of
ExactSizeIterator
is not specified, to allow the use of
Iterator::flat_map
in implementations of this trait.