【问题标题】:How do I implement an `apply_n_times` function?如何实现 `apply_n_times` 函数?
【发布时间】:2020-08-05 14:33:16
【问题描述】:

我如何实现一个 apply_n_times 函数,它得到一个函数 f: T -> T 和一个数字 n,结果将是一个应用 f ntimes 的函数?

例如apply_n_times(f, 0) 等于 |x| xapply_n_times(f, 3) 等于 |x| f(f(f(x)))

这个函数没有更深层次的意义,我只是出于学习的原因想实现它。

我当前的代码:

fn apply_n_times<T>(f: Fn(T) -> T, n: i32) -> dyn Fn(T) -> T {
    if n < 0 {
        panic!("Cannot apply less than 0 times!");
    }

    if n == 1 {
        |x: T| x
    } else {
        |x| f(apply_n_times(f, n - 1)(x))
    }
}

fn times_two(n: i32) -> i32 {
    return n * 2;
}

fn main() {
    println!("{}", apply_n_times(times_two, 0)(3));
    println!("{}", apply_n_times(times_two, 1)(3));
    println!("{}", apply_n_times(times_two, 3)(3));
}

我在 Rust 书的第 13 章,但我向前搜索了一下。我可能必须返回Box,但我不太确定。我试过了,失败了。

我也想把签名改成这个,但这只会导致问题:

fn apply_n_times<F, T>(f: F, n: i32) -> F
where
    F: Fn(T) -> T,

不幸的是,编译器错误对我没有帮助;他们说低级有什么问题,但我是在兜圈子。

【问题讨论】:

标签: rust closures


【解决方案1】:
fn apply_n_times<T>(f: impl Fn(T) -> T, n: usize) -> impl Fn(T) -> T {
    move |arg| (0..n).fold(arg, |a, _| f(a))
}

使用usize 可以避免进行否定检查。考虑使用FnMut 而不是Fn,因为它对函数用户来说更灵活。

另见:

【讨论】:

  • 谢谢,特别是参考:)!
  • 我认为在这里使用u32u64 更有意义,因为长度不用作指针偏移或类似的东西,并且它的大小不需要依赖于平台。
猜你喜欢
  • 2017-12-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-29
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多