rand_functors/strategies/
sampler.rs

1use rand::distr::uniform::SampleUniform;
2use rand::distr::StandardUniform;
3use rand::prelude::*;
4
5use crate::{
6    FlattenableRandomStrategy, Inner, RandomStrategy, RandomVariable, RandomVariableRange,
7};
8
9/// Samples the desired distributions and produces a single possible output of
10/// the random process.
11#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
12pub struct Sampler;
13
14impl RandomStrategy for Sampler {
15    type Functor<I: Inner> = I;
16
17    #[inline]
18    fn fmap<A: Inner, B: Inner, F: Fn(A) -> B>(f: Self::Functor<A>, func: F) -> Self::Functor<B> {
19        func(f)
20    }
21
22    #[inline]
23    fn fmap_rand<A: Inner, B: Inner, R: RandomVariable, F: FnOnce(A, R) -> B>(
24        f: Self::Functor<A>,
25        rng: &mut impl Rng,
26        func: F,
27    ) -> Self::Functor<B>
28    where
29        StandardUniform: Distribution<R>,
30    {
31        func(f, rng.random())
32    }
33
34    #[inline]
35    fn fmap_rand_range<A: Inner, B: Inner, R: RandomVariable + SampleUniform, F: Fn(A, R) -> B>(
36        f: Self::Functor<A>,
37        range: impl RandomVariableRange<R>,
38        rng: &mut impl Rng,
39        func: F,
40    ) -> Self::Functor<B>
41    where
42        StandardUniform: Distribution<R>,
43    {
44        func(f, rng.random_range(range))
45    }
46}
47
48impl FlattenableRandomStrategy for Sampler {
49    #[inline]
50    fn fmap_flat<A: Inner, B: Inner, F: FnMut(A) -> Self::Functor<B>>(
51        f: Self::Functor<A>,
52        mut func: F,
53    ) -> Self::Functor<B> {
54        func(f)
55    }
56}