Scala咖喱功能

时间:2020-10-25 12:59:21

标签: scala functional-programming

我有两种方法,nTimesnTimesBetter。这两个函数都对作为参数传递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))

以下是使用某些函数fn = 3x = 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))这样称呼。

1 个答案:

答案 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是尾递归的。