在scala中将函数调用作为参数传递,函数是否首先求值?
我只是在玩Scala中foldlLeft的实现在scala中将函数调用作为参数传递,函数是否首先求值?,scala,recursion,tail-recursion,Scala,Recursion,Tail Recursion,我只是在玩Scala中foldlLeft的实现 def foldLeft[A,B] (as: List[A], z: B) (f: (B, A) => B): B = as match { case Nil => z case Cons(x, xs) => foldLeft(xs, f(z,x)) (f) } 在这个实现中,f(z,x)在递归调用中作为z的参数给出,但我想知道这实际上是如何工作的? 当递归调用发生时,foldLeft()是否接收执行f(z,b)的值,或
def foldLeft[A,B] (as: List[A], z: B) (f: (B, A) => B): B = as match {
case Nil => z
case Cons(x, xs) => foldLeft(xs, f(z,x)) (f)
}
在这个实现中,f(z,x)
在递归调用中作为z
的参数给出,但我想知道这实际上是如何工作的?
当递归调用发生时,foldLeft()
是否接收执行f(z,b)
的值,或者是否以编写函数调用的方式接收函数调用,然后在需要时执行
例如:
如果我们使用以下值调用foldLeft()
def foldLeft[A,B] ([1,2,3], 0) (f: (x, y) => x + y): B = as match {
case Nil => z
case Cons(x, xs) => foldLeft([2,3], f(0,1)) (f)
}
下一次执行foldLeft()
时是否会这样,其中z等于f()
的值
或者它是这样工作的,foldLeft()
本身接收调用
def foldLeft[A,B] ([2,3], f(0,1)) (f: (x, y) => x + y): B = as match {
case Nil => z
case Cons(x, xs) => foldLeft([3], f(f(1,0),2)) (f)
}
问题本质上是关于何时对尾部递归函数的值求值?Scala与几乎所有主流语言一样,是一种严格的语言,具有急切求值策略和按值传递参数的语义 这意味着 然而,我所写的事实并不完全正确:这只是默认情况 有两种方法可以偏离默认值:
f(z,x)
将在对foldLeft
z
的递归调用是类型B之前被完全计算,因此您只能传递B,不能传递函数,不能传递按名称参数,不能传递其他任何东西;只是一个普通的B。另外,f(z,x)
是对函数的一种求值,它将在生成B之前被执行(记住Scala是一种渴望的语言,而不是像Haskell那样懒惰的语言)。
def foldLeft[A,B] ([2,3], f(0,1)) (f: (x, y) => x + y): B = as match {
case Nil => z
case Cons(x, xs) => foldLeft([3], f(f(1,0),2)) (f)
}