diff options
| author | Jakub Wieczorek <jakub@jakub.cc> | 2014-07-07 00:50:53 +0200 |
|---|---|---|
| committer | Jakub Wieczorek <jakub@jakub.cc> | 2014-07-13 11:47:40 +0200 |
| commit | ed54162e86cd00b7a4ced8957aac7f56897f6fb5 (patch) | |
| tree | 675f830b5b9cd3b28ff9f976dab70c06b30735a4 | |
| parent | 88231a9b70574990363262e6be8451df8782e4ca (diff) | |
| download | rust-ed54162e86cd00b7a4ced8957aac7f56897f6fb5.tar.gz rust-ed54162e86cd00b7a4ced8957aac7f56897f6fb5.zip | |
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.
| -rw-r--r-- | src/libcore/iter.rs | 29 | ||||
| -rw-r--r-- | src/libcoretest/iter.rs | 9 |
2 files changed, 34 insertions, 4 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 80b784250f0..855bccb07a7 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -64,14 +64,14 @@ the rest of the rust manuals. */ +use clone::Clone; use cmp; +use cmp::{PartialEq, PartialOrd, Ord}; +use mem; 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 option::{Option, Some, None}; use uint; -use mem; /// 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 diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 86b5ffece41..64c33609399 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -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)); +} |
