I have two methods, nTimes
and nTimesBetter
. Both functions perform an operation on a function passed as a parameter n times.
The method nTimes
takes a function f
, the number of times it has to be called n
and the initial value for the function to work on x
def nTimes(f:Int=>Int,n:Int,x:Int):Int =
if (n <= 0) x
else
nTimes(f, n-1, f(x))
The following is what happens when the method is called with some function f
, n = 3
and x = 1
:
// nTimes(f,3,1)
// nTimes(f,2,f(1))
// nTimes(f,1,f(f(1)))
// nTimes(f,0,f(f(f(1))))
The method nTimesBetter
method does not take initial value, but only a function f
and the number of times n
the function should be called
def nTimesBetter(f:Int=>Int,n:Int):(Int=>Int)=
if (n <= 0) x => x
else
x => nTimesBetter(f, n-1)(f(x))
nTimesBetter
returns a function that can be applied to an initial value
println(nTimes((x:Int)=>x+1,10,1))
val plus10 = nTimesBetter((x:Int)=>x+1,10)
println(plus10(1))
Can someone explain nTimesBetter
with a stack of execution and use of (x:Int) => nTimesBetter(f,n-1)(f(x))
? Why (f(x))
is called like this.
The main difference between these two is that the former returns a value and the latter returns a function Int => Int
. The stack is far less readable than the one from nTimes
but here it is:
// 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))
Why (f(x)) is called like this?
Because nTimesBetter
returns a function that needs an argument. You can rewrite nTimesBetter
as:
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
is not that better because nTimes
is tail recursive.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.