sample_std/
recursive.rs

1//! Some simple helpers for recursive sampling.
2use crate::{Random, Sample};
3use std::ops::Range;
4
5pub trait Recursion {
6    type Output;
7
8    fn recurse(&self, g: &mut Random, inner: RecursiveSampler<Self>) -> Self::Output
9    where
10        Self: Sized;
11}
12
13#[derive(Debug, Clone)]
14pub struct RecursiveSampler<G> {
15    pub depth: Option<Range<usize>>,
16    pub node: G,
17}
18
19impl<G: Clone> RecursiveSampler<G> {
20    fn lower(&self) -> Self {
21        let depth = self
22            .depth
23            .as_ref()
24            .map(|d| d.start.saturating_sub(1)..d.end.saturating_sub(1));
25        Self {
26            depth,
27            ..self.clone()
28        }
29    }
30}
31
32impl<G, N> Sample for RecursiveSampler<G>
33where
34    G: Recursion<Output = N> + Sample<Output = N> + Clone,
35    N: 'static,
36{
37    type Output = N;
38
39    fn generate(&mut self, g: &mut Random) -> Self::Output {
40        match &self.depth {
41            Some(depth) => {
42                if depth.start > 0 {
43                    self.node.recurse(g, self.lower())
44                } else {
45                    if depth.end > 0 {
46                        self.node.recurse(g, self.lower())
47                    } else {
48                        self.node.generate(g)
49                    }
50                }
51            }
52            None => self.node.recurse(g, self.lower()),
53        }
54    }
55}