Add an iterate function to core::iter

Implementation by Kevin Ballard.

The function returns an Unfold iterator producing an infinite stream
of results of repeated applications of the function, starting from
the provided seed value.
This commit is contained in:
Jakub Wieczorek 2014-07-07 00:50:53 +02:00
parent 88231a9b70
commit ed54162e86
2 changed files with 36 additions and 6 deletions

View File

@ -64,14 +64,14 @@ the rest of the rust manuals.
*/
use cmp;
use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int};
use option::{Option, Some, None};
use ops::{Add, Mul, Sub};
use cmp::{PartialEq, PartialOrd, Ord};
use clone::Clone;
use uint;
use cmp;
use cmp::{PartialEq, PartialOrd, Ord};
use mem;
use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int};
use ops::{Add, Mul, Sub};
use option::{Option, Some, None};
use uint;
/// Conversion from an `Iterator`
pub trait FromIterator<A> {
@ -2192,6 +2192,27 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) }
}
type IterateState<'a, T> = (|T|: 'a -> T, Option<T>, bool);
/// An iterator that repeatedly applies a given function, starting
/// from a given seed value.
pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
/// Creates a new iterator that produces an infinite sequence of
/// repeated applications of the given function `f`.
#[allow(visible_private_types)]
pub fn iterate<'a, T: Clone>(f: |T|: 'a -> T, seed: T) -> Iterate<'a, T> {
Unfold::new((f, Some(seed), true), |st| {
let &(ref mut f, ref mut val, ref mut first) = st;
if *first {
*first = false;
} else {
val.mutate(|x| (*f)(x));
}
val.clone()
})
}
/// Functions for lexicographical ordering of sequences.
///
/// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires

View File

@ -833,3 +833,12 @@ fn test_min_max_result() {
let r = MinMax(1i,2);
assert_eq!(r.into_option(), Some((1,2)));
}
#[test]
fn test_iterate() {
let mut it = iterate(|x| x * 2, 1u);
assert_eq!(it.next(), Some(1u));
assert_eq!(it.next(), Some(2u));
assert_eq!(it.next(), Some(4u));
assert_eq!(it.next(), Some(8u));
}