我正在学习函数式编程语言课程,而且我很难理解'函数作为参数'的上下文中的递归
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
我可以理解更简单的递归模式,例如在列表中添加数字,或'power of'函数但我无法理解这个函数'n_times'如何通过调用自身来评估?可以解释这个功能是如何工作的吗?
我已经使用scala标记,因为我正在学习这门课程以提高我对scala的理解(以及函数式编程),我认为这是一种常见的模式,因此可以提供建议吗?
答案 0 :(得分:6)
如果n
为0,则返回x
。
否则,返回f (n_times(f , n - 1 , x))
。
n_times
做什么?它需要f
x
,n
次或同等地调用f
:调用n_times(f, n - 1, x)
,结果为f
(调用n-1
x
上的f
次。
通过调用f
注意我的意思是:
调用f(f(f(x)))
3次:f
2次致电f(f(x))
:{{1}}
答案 1 :(得分:4)
手动扩展。我打算致电n_times
nx
以节省空间。
核心操作是
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 ) ... ) )
答案 2 :(得分:3)
函数n_times
在n = 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
答案 3 :(得分:0)
同样的递归思考你已经知道的东西,只是混合了另一个概念:高阶函数。
n_times获得一个函数(f)作为参数,因此n_times是一个更高阶的函数,它又能够在他的身体中应用这个f函数。实际上这是他的工作,应用f次x。
那你如何对x应用f n次?好吧,如果你申请了n-1次
n_times(f , n - 1 , x)
,然后再申请一次。
f (n_times(f , n - 1 , x))
你必须像往常一样停止递归,即x =
的n = 0情况