A piece of code using high order function

/// Returns an anonymous function that applies the given function `f` for `n` times.
///
/// For instance, `repeat(3, f)(x)` roughly translates to `f(f(f(x)))`.
fn repeat<T, F: FnMut(T) -> T>(n: usize, mut f: F) -> impl FnMut(T) -> T {
    move |num| {
        let mut mnum = num;
        let mut mn = n;
        while mn != 0 {
            mnum = f(mnum);
            mn -= 1;
        }
        mnum
    }
}

/// Applies the given function `f` for `i` times for the `i`-th element of the given vector.
///
/// For instance, `funny_map(f, [v0, v1, v2, v3])` roughly translates to `[v0, f(v1), f(f(v2)), f(f(f(v3)))]`.
fn funny_map<T, F: Fn(T) -> T>(f: F, vs: Vec<T>) -> Vec<T> {
    todo!()
}

#[test]
fn test_repeat() {
    for i in 0..10 {
        assert_eq!(42 + 2 * i, repeat(i, |x| x + 2)(42));
    }
}

#[test]
fn test_funny_map() {
    assert_eq!(
        vec![0, 3, 6, 9, 12],
        funny_map(|x| x + 2, vec![0, 1, 2, 3, 4])
    );
}

This is the playground link.'

If I use the repeat in funny_map, f will move into repeat and cannot reused.Any ideas on how to fix it?

You can just pass a reference, then.

By the way, there are several other problems:

  • funny_map() doesn't need an Fn, you could use an FnMut().
  • it could also just take and return an iterator instead of vectors.
  • repeat() could be simplified a lot.

All in all, this compiles, passes the tests, and is generally better.

2 Likes

This is really helpful! Thank you very much!!! :smiley_cat: :smiley_cat: :smiley_cat: