BurntSushi / quickcheck

Automated property based testing for Rust (with shrinking).
The Unlicense
2.4k stars 149 forks source link

Implement something like choose_weighted for `Gen` #312

Open DrSplinter opened 2 years ago

DrSplinter commented 2 years ago

Can we include something like frequency from Haskell's QuickCheck? It will generalize this pattern and make it more convenient to use, for example:

g.choose_weighted(&[
    (10, g.gen_range(0..0xB0) as u8 as char),
    (2, ...),
    (5, ...),
    (1, ...),
    (1, ...),
    (1, ...),
])

The implementation can be something like this:

impl Gen {

    pub fn choose_weighted<'a, T>(&mut self, slice: &'a [(u32, T)]) -> Option<&'a T> {
        slice.choose_weighted(&mut self.rng, |item| item.0).ok().map(|item| &item.1)
    }

}

I know that in this particular example can be problem with eager evaluation which is not problem in Haskell since it is lazy, however, we can solve it by adding another associated function which chooses from closures instead of values. In other words, do it exactly like it is done for Result with and/and_then and or/or_else functions.

What do you think?