【发布时间】:2015-08-16 19:26:16
【问题描述】:
我得到以下代码:
trait Stream[+A] {
def uncons: Option[(A, Stream[A])]
def foldRight[B](z: => B)(f: (A, => B) => B): B = {
uncons.map(t => {
f(t._1, t._2.foldRight(z)(f))
}).getOrElse(z)
}
def exists(p: A => Boolean) =
foldRight(false)((x, acc) => acc || p(x))
def forAll(p: A => Boolean) =
foldRight(true)((x, acc) => p(x) && acc)
}
object Stream {
def cons[A](h: => A, t: => Stream[A]): Stream[A] =
new Stream[A] {
lazy val uncons = Some((h, t))
}
}
然后我以惰性方式创建一个 Stream 并调用 exists 方法来检查评估了哪些流元素:
println(Stream.cons({println("5"); 1}, Stream.cons({println("6"); 2}, Stream.cons({println("7"); 3}, Stream.cons({println("8"); 4}, Stream.empty)))).exists(_ == 1))
我看到的是:
5
6
7
8
true
所以所有元素都被评估了,尽管只有第一个就足够了。我似乎明白为什么exists 会这样做。
然后我运行以下代码:
println(Stream.cons({println("13"); 1}, Stream.cons({println("14"); 2}, Stream.cons({println("15"); 3}, Stream.cons({println("16"); 4}, Stream.empty)))).forAll(_ < 2))
并查看以下内容:
13
14
false
只要forAll 遇到一个不满意的值,它就会终止遍历。
但是为什么forAll 会那样做呢?它和exists 的关键区别是什么?
【问题讨论】:
标签: scala lazy-evaluation lazy-sequences