libcore: add an UnfoldrIterator like Haskell's unfoldr
This commit is contained in:
parent
d7a2ae6c42
commit
90313b789c
@ -261,6 +261,28 @@ impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UnfoldrIterator<'self, A, St> {
|
||||
priv f: &'self fn(&mut St) -> Option<A>,
|
||||
priv state: St
|
||||
}
|
||||
|
||||
pub impl<'self, A, St> UnfoldrIterator<'self, A, St> {
|
||||
#[inline]
|
||||
fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St) -> UnfoldrIterator<'self, A, St> {
|
||||
UnfoldrIterator {
|
||||
f: f,
|
||||
state: initial_state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, St> Iterator<A> for UnfoldrIterator<'self, A, St> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<A> {
|
||||
(self.f)(&mut self.state)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -326,4 +348,25 @@ mod tests {
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unfoldr() {
|
||||
fn count(st: &mut uint) -> Option<uint> {
|
||||
if *st < 10 {
|
||||
let ret = Some(*st);
|
||||
*st += 1;
|
||||
ret
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let mut it = UnfoldrIterator::new(count, 0);
|
||||
let mut i = 0;
|
||||
for it.advance |counted| {
|
||||
assert_eq!(counted, i);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, 10);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user