Skip to content

Commit 90313b7

Browse files
huonwthestinger
authored andcommitted
libcore: add an UnfoldrIterator like Haskell's unfoldr
1 parent d7a2ae6 commit 90313b7

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/libcore/iterator.rs

+43
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,28 @@ impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<T> {
261261
}
262262
}
263263

264+
pub struct UnfoldrIterator<'self, A, St> {
265+
priv f: &'self fn(&mut St) -> Option<A>,
266+
priv state: St
267+
}
268+
269+
pub impl<'self, A, St> UnfoldrIterator<'self, A, St> {
270+
#[inline]
271+
fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St) -> UnfoldrIterator<'self, A, St> {
272+
UnfoldrIterator {
273+
f: f,
274+
state: initial_state
275+
}
276+
}
277+
}
278+
279+
impl<'self, A, St> Iterator<A> for UnfoldrIterator<'self, A, St> {
280+
#[inline]
281+
fn next(&mut self) -> Option<A> {
282+
(self.f)(&mut self.state)
283+
}
284+
}
285+
264286
#[cfg(test)]
265287
mod tests {
266288
use super::*;
@@ -326,4 +348,25 @@ mod tests {
326348
}
327349
assert_eq!(i, ys.len());
328350
}
351+
352+
#[test]
353+
fn test_unfoldr() {
354+
fn count(st: &mut uint) -> Option<uint> {
355+
if *st < 10 {
356+
let ret = Some(*st);
357+
*st += 1;
358+
ret
359+
} else {
360+
None
361+
}
362+
}
363+
364+
let mut it = UnfoldrIterator::new(count, 0);
365+
let mut i = 0;
366+
for it.advance |counted| {
367+
assert_eq!(counted, i);
368+
i += 1;
369+
}
370+
assert_eq!(i, 10);
371+
}
329372
}

0 commit comments

Comments
 (0)