我有两种方法,nTimes
和nTimesBetter
。这两个函数都对作为参数传递n次的函数执行操作。
方法nTimes
接受一个函数f
,必须调用的次数n
和该函数在x
上起作用的初始值>
def nTimes(f:Int=>Int,n:Int,x:Int):Int =
if (n <= 0) x
else
nTimes(f, n-1, f(x))
以下是使用某些函数f
,n = 3
和x = 1
调用该方法时发生的情况:
// nTimes(f,3,1)
// nTimes(f,2,f(1))
// nTimes(f,1,f(f(1)))
// nTimes(f,0,f(f(f(1))))
方法nTimesBetter
的值不是初始值,而是函数f
和调用次数n
的初始值
def nTimesBetter(f:Int=>Int,n:Int):(Int=>Int)=
if (n <= 0) x => x
else
x => nTimesBetter(f, n-1)(f(x))
nTimesBetter
返回可以应用于初始值的函数
println(nTimes((x:Int)=>x+1,10,1))
val plus10 = nTimesBetter((x:Int)=>x+1,10)
println(plus10(1))
有人可以通过一堆执行和使用nTimesBetter
来解释(x:Int) => nTimesBetter(f,n-1)(f(x))
吗?为什么(f(x))
这样称呼。
答案 0 :(得分:4)
这两者之间的主要区别在于,前者返回一个值,而后者返回一个函数Int => Int
。堆栈的可读性远低于nTimes
的堆栈,但是在这里是:
// nTimesBetter(f, 3)
// x => nTimesBetter(f, 2)(f(x))
// x => (x => nTimesBetter(f, 1)(f(x)))(f(x))
// x => (x => (x => (x => x)(f(x)))(f(x)))(f(x))
为什么这样调用(f(x))?
因为nTimesBetter
返回需要参数的函数。您可以将nTimesBetter
重写为:
def nTimesBetter(f: Int => Int, n: Int): Int => Int =
if (n <= 0) x => x
else {
val function: Int => Int = nTimesBetter(f, n - 1) // Creates a function
x => function(f(x)) // Uses f(x) as an argument
}
PS。 nTimesBetter
并不是更好,因为nTimes
是尾递归的。