4

Haskell's iterate function repeatedly applies a function to a value to generate a series of values. For example, applying (^2) to 2 generates 2, 2^2, 2^2^2, 2^2^2^2, ... (2, 4, 16, 256, ...)

Is there an equivalent in Rust?

SirDarius
  • 41,440
  • 8
  • 86
  • 100
  • Possible duplicate of [Can you create a function that takes another function and a parameter and returns a lazy stream of nested function calls?](https://stackoverflow.com/questions/52902081/can-you-create-a-function-that-takes-another-function-and-a-parameter-and-return) – Sven Marnach Feb 21 '19 at 19:47

3 Answers3

6

This does not exist in the standard library, however the itertools crate has iterate

Creates a new iterator that infinitely applies function to value and yields results.

use itertools::iterate;

itertools::assert_equal(iterate(1, |&i| i * 3).take(5), vec![1, 3, 9, 27, 81]);
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
SirDarius
  • 41,440
  • 8
  • 86
  • 100
2

As of Rust 1.34, you can use std::iter::successors

So for this problem you would do something like this:

playpen

use std::iter::successors;

fn main() {
    let v = successors(Some(2_u128), |n| n.checked_mul(*n)).collect::<Vec<_>>();
    assert_eq!(v, vec![2, 4, 16, 256, 65536, 4294967296, 18446744073709551616]);

    for i in successors(Some(2_u128), |n| n.checked_mul(*n)) {
        println!("{}", i);
    }
}

Also look at std::iter::from_fn, it can be quite a bit more powerful.

Dan N
  • 167
  • 1
  • 7
0

itertools::iterate seems to be what you want.

Jmb
  • 18,893
  • 2
  • 28
  • 55