pub fn delay<I: Iterator, F: FnOnce() -> I>(new: F) -> Delayed<I, F> ⓘExpand description
Wraps an iterator created by new on the first call to
next().
For example, consider Haskell’s canonical zipWith implementation:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)A naive translation to Rust would cause infinite recursion. We can emulate Haskell’s lazy evaluation by delaying the recursive calls:
use iter_utils::delay;
/// Returns an inefficient iterator over the Fibonacci numbers.
fn fibs() -> Box<dyn Iterator<Item = u32>> {
Box::new(
[0, 1]
.into_iter()
.chain(delay(fibs).zip(delay(fibs).skip(1)).map(|(x, y)| x + y)),
)
}
for (got, want) in fibs().zip([0, 1, 1, 2, 3, 5, 8, 13]) {
assert_eq!(got, want);
}