0

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.

1
  • 2
    side note: the easy way to write nTimesBetter when you already have nTimes is def nTimesBetter(f: Int => Int, n: Int) = nTimes(f, n, _) Commented Oct 25, 2020 at 15:50

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

What will be sequence of execution of x => (x => (x => (x => x)(f(x)))(f(x)))(f(x)) ? Innermost expression will be evaluated first like stack function
Exactly. First (x => x)(f(x)) will be evaluated to f(x). Then we have (x => f(x))(f(x)) which is f(f(x)). Finally we will get a function x => f(f(f(x))).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.