libcore: add an UnfoldrIterator like Haskell's unfoldr

This commit is contained in:
Huon Wilson 2013-04-20 00:07:07 +10:00 committed by Daniel Micay
parent d7a2ae6c42
commit 90313b789c

View File

@ -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);
}
}