【问题标题】:Cannot understand 'functions as arguments' recursion无法理解“作为参数的函数”递归
【发布时间】:2013-01-16 04:29:28
【问题描述】:

我正在学习函数式编程语言课程,但在“作为参数的函数”的上下文中我很难理解递归

fun n_times(f , n , x) = 
    if n=0
    then x
    else f (n_times(f , n - 1 , x))

fun double x = x+x;

val x1 = n_times(double , 4 , 7);

the value of x1 = 112

这将 'x' 加倍 'n' 次,因此 7 加倍 4 次 = 112

我可以理解更简单的递归模式,例如在列表中添加数字或函数的“幂”,但我无法理解这个函数“n_times”如何通过调用自身来评估?能否解释一下这个函数是如何工作的?

我在学习这门课程时标记了 scala,以提高我对 scala(以及函数式编程)的理解,我认为这是一种常见的模式,所以可以提供建议吗?

【问题讨论】:

  • 我想这对我来说似乎太明显了。尝试重写方法(可能使用 3 而不是 4 的 n),其中重写顶层调用和每个递归调用,结果将实际参数值替换为对函数体中形式参数的引用.

标签: scala recursion functional-programming sml ml


【解决方案1】:

同样的递归思考你已经知道的,只是混合了另一个概念:高阶函数。

n_times 得到一个函数 (f) 作为参数,因此 n_times 是一个高阶函数,它又能够在他的身体中应用这个 f 函数。实际上这是他的工作,将 f n 次应用于 x。

那么你如何将 f n 次应用于 x 呢?好吧,如果你申请了n-1次

n_times(f , n - 1 , x)

,然后你再申请一次。

f (n_times(f , n - 1 , x))

您必须像往常一样停止递归,即 x 的 n=0 情况。

【讨论】:

    【解决方案2】:

    只需手动扩展。我要打电话给n_timesnx以节省空间。

    核心操作是

    nx(f, n, x) -> f( nx(f, n-1, x))
    

    终止于

    nx(f, 0, x) -> x
    

    当然,

    nx(f, 1, x) -> f( nx(f, 0, x) ) -> f( x )
    nx(f, 2, x) -> f( nx(f, 1, x) ) -> f( f( x ) )
    ...
    nx(f, n, x) -> f( nx(f,n-1,x) ) -> f( f( ... f( x ) ... ) )
    

    【讨论】:

    • 这是我的建议。我太懒惰了,不能为 OP 做这件事。
    【解决方案3】:

    函数n_timesn = 0 时具有基本情况,否则为归纳情况。您在归纳案例上递归,直到在基本案例上终止。

    这是一个说明性的跟踪:

       n_times(double, 4, 7)
    ~> double (n_times(double, 3, 7)) (* n = 4 > 0, inductive case *)
    ~> double (double (n_times(double, 2, 7))) (* n = 3 > 0, inductive case *)
    ~> double (double (double (n_times(double, 1, 7)))) (* n = 2 > 0, inductive case *)
    ~> double (double (double (double (n_times(double, 0, 7))))) (* n = 1 > 0, inductive case *)
    ~> double (double (double (double 7))) (* n = 0, base case *)
    ~> double (double (double 14)) 
    ~> double (double 28)
    ~> double 56
    ~> 112
    

    【讨论】:

      【解决方案4】:

      如果n 为0,则返回x

      否则返回f (n_times(f , n - 1 , x))

      n_times 是做什么的?它需要使用xn 次调用f 的结果,或者等效地:使用n_times(f, n - 1, x) 的结果调用f(在x 上调用fn-1 次)。

      请注意调用f 我的意思是例如:

      致电f 3 次:f(f(f(x)))

      致电f 2 次:f(f(x))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-03
        • 1970-01-01
        • 2014-10-29
        • 1970-01-01
        • 2020-06-08
        • 2023-03-25
        • 2021-08-14
        • 2018-05-31
        相关资源
        最近更新 更多