在scala中传递函数调用作为参数,函数会先求值吗?

问题描述

我只是在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)的执行值,还是以编写方式接收函数调用,然后在需要时执行?

示例: 如果我们使用以下值调用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,f(0,1)) (f)
}

下一个foldLeft()的执行是否会这样,其中z等于f()的值?

def foldLeft[A,B] ([2,1) (f: (x,f(1,2)) (f)
}

还是这样工作,foldLeft()会自己接听电话?

def foldLeft[A,1)) (f: (x,xs) => foldLeft([3],f(f(1,0),2)) (f)
}

问题本质上是关于何时评估尾递归函数的值?

解决方法

与几乎所有主流语言一样,

Scala是一种 strict 语言,具有渴望评估策略和 pass-by-value 自变量传递语义

这意味着all arguments to a method or function call will be fully evaluated before being passed into the method or function

但是,我写的实际上并不完全正确:仅仅是默认

有两种方法可以偏离默认设置:

  1. lazy modifier很有价值,很懒。
  2. by-name parameters是按名称而不是按值传递的。

#1在这里不适用。 #2需要在参数列表中显式声明,此处不是这种情况。

因此,我们可以得出结论,是的,f(z,x)将在递归调用foldLeft之前得到充分评估。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...