I'm looking at implementing the basic functional not-quite-Eratosthenes prime stream in Rust. I like to try it when I start learning a language.
Here's the bog standard Haskell version:
primes :: [Integer]
primes = sieve (2 : [3, 5..])
where
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p /= 0]
in Rust, I think a reasonable transliteration is something like:
struct Primes {
iter: Option<Box<Iterator<Item=u32>>>
}
impl Iterator for Primes {
type Item = u32;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
let mut iter = self.iter.take().unwrap();
let res = iter.next().unwrap();
self.iter = Some(Box::new(iter.filter( move |x| x % res != 0)));
Some(res)
}
}
fn main() {
let primes = Primes { iter: Some(Box::new(2..)) };
for p in primes.take(20) {
println!("{}", p);
}
}
Leaving aside the algorithm (of course there are nicer ways to do primes!),
this feels a bit verbose - is there a simpler way to construct an iterator with accumulating filters? The Option
of Box
feels quite clunky, but if I understand right, that's the best way to replace a field on self
.