在浏览qazxsw poi时,我遇到了以下代码片段:
Functional Programming in Scala
然后,作者继续说明以下内容:
这看起来非常类似于我们为List编写的foldRight,但请注意我们的组合函数f在其第二个参数中是非严格的。如果f选择不评估其第二个参数,则会提前终止遍历。我们可以通过使用foldRight来实现exists来检查这一点,它检查Stream中的任何值是否与给定的谓词匹配。
然后作者陈述如下:
def foldRight[A](z: => B)(f: (A,=>B) => B):B = uncons match {
case Some((h,t)) => f(h,t.foldRight(z)(f))
case None => z
}
我的问题是组合函数f如何导致exists方法的提前终止?我不认为我能够理解文本中的情况。
在def exists(p: A => Boolean): Boolean =
foldRight(false)((a, b) => p(a) || b)
,提供给f(h,t.foldRight(z)(f))
的第一个论点是f
,第二个论点是h
。 t.foldRight(z)(f)
定义的方式是它的foldRight
参数的第二个参数是一个名字参数,在需要之前不会被评估(并且每次需要时都会被评估)。因此在f
中,f: (A, =>B) => B
类型的第一个参数是一个普通参数,但A
类型的第二个参数是一个名字参数。
所以假装你这样定义B
:
f
如果f(a: A, b: => Boolean): Boolean = predicate(a) || b
为真,那么predicate(a)
永远不需要,永远不会被评估。这就是运营商的运作方式。
所以说b
适用于一些exists
。对于将要存在的第一个未解决的元素(其中Stream
为真),此代码:
p(h)
与此代码相同(我们假设我们有一个非空流,所以我们可以删除第二种情况):
uncons match {
case Some((h,t)) => f(h,t.foldRight(z)(f))
case None => z
}
这相当于(扩展f(h,t.foldRight(z)(f))
):
f
但p(h) || t.foldRight(z)(f)
是真的如此:
p(h)
这与true || t.foldRight(z)(f)
相同,无需继续调用true
,因此提前终止!