Skip to content

Commit

Permalink
Add an iterate function to core::iter
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Jakub Wieczorek committed Jul 13, 2014
1 parent 88231a9 commit ed54162
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
29 changes: 25 additions & 4 deletions src/libcore/iter.rs
Expand Up @@ -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> {
Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/libcoretest/iter.rs
Expand Up @@ -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));
}

5 comments on commit ed54162

@bors
Copy link
Contributor

@bors bors commented on ed54162 Jul 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on ed54162 Jul 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging jakub-/rust/iterate = ed54162 into auto

@bors
Copy link
Contributor

@bors bors commented on ed54162 Jul 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jakub-/rust/iterate = ed54162 merged ok, testing candidate = fbeee04

@bors
Copy link
Contributor

@bors bors commented on ed54162 Jul 13, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = fbeee04

Please sign in to comment.