Created
June 13, 2018 04:47
-
-
Save jimblandy/4142c24d7bda3ae76cf7638b085c632e to your computer and use it in GitHub Desktop.
A Rust `unfold` function, to build an iterator by repeatedly applying a closure.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() { | |
//let i = (0i32..).scan((0,1), |s,_| { *s = (s.1, s.0 + s.1); Some(s.0) }); | |
let i = unfold((0, 1), |(a, b)| Some(((b, a+b), b))); | |
let v: Vec<i32> = i.take(20).collect(); | |
println!("{:?}", v); | |
} | |
struct Unfolder<F, T>(F, Option<T>); | |
impl<T, U, F> Iterator for Unfolder<F, T> | |
where F: FnMut(T) -> Option<(T, U)> | |
{ | |
type Item = U; | |
fn next(&mut self) -> Option<U> { | |
self.1.take() | |
.map_or(None, &mut self.0) | |
.map_or(None, |(next_v, item)| { | |
self.1 = Some(next_v); | |
Some(item) | |
}) | |
} | |
} | |
fn unfold<T, U, F>(t: T, f: F) -> impl Iterator<Item=U> | |
where F: FnMut(T) -> Option<(T, U)> | |
{ | |
Unfolder(f, Some(t)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment