LazyList .scanLeft() 在空列表上调用
LazyList .scanLeft() called on an empty List
我一直在用 Scala 做一些 Euler 问题,然后我找到了 #2 问题的非常优雅的解决方案。但是我在理解它为什么起作用时遇到了一些问题。据我所知,它需要 1
并将其添加到 fibbonaciNumbers.scanLeft(1)(_ + _)
以初始化同一个数组。如何调用 scanLeft()
on 和此时为空的 LazyList?
/**
* Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
* the first 10 terms will be:
* 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
* By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the
* even-valued terms.
*
* Result:
*/
object Problem2 {
def main(args: Array[String]): Unit = {
println("The result is " + fibbonaciNumbersSum(4000000))
}
// Why is it possible to call .scanLeft on an empty list (because it's empty in the moment we call it, right?)
lazy val fibbonaciNumbers: LazyList[Int] = 1 #:: fibbonaciNumbers.scanLeft(1)(_ + _)
private def fibbonaciNumbersSum(limit: Int) = fibbonaciNumbers.takeWhile(_ <= limit).filter(_ % 2 == 0).sum
}
LazyList 不为空。查看 Stream 的文档:
/** Construct a stream consisting of a given first element followed by elements
* from a lazily evaluated Stream.
*/
def #::[B >: A](hd: B): Stream[B] = cons(hd, tl)
所以至少你的 Stream/LazyList 有一个第一个元素(已评估)并且是
中的 1
1 #:: fibbonaciNumbers.scanLeft...
列表中的第二个元素是来自 scanLeft 的 1 ... 然后 scanLeft 接管以生成其余元素 2、3、5...但它们只会在以下情况下被评估需要。但是什么时候需要它们? ... 当你打电话给
println("The result is " + fibbonaciNumbersSum(4000000))
这将触发
的评估
fibbonaciNumbers.takeWhile(_ <= limit).filter(_ % 2 == 0).sum
因此,只要 Stream / LazyList 中的每个元素小于限制,就会对其进行评估,并完成过滤和求和。
我一直在用 Scala 做一些 Euler 问题,然后我找到了 #2 问题的非常优雅的解决方案。但是我在理解它为什么起作用时遇到了一些问题。据我所知,它需要 1
并将其添加到 fibbonaciNumbers.scanLeft(1)(_ + _)
以初始化同一个数组。如何调用 scanLeft()
on 和此时为空的 LazyList?
/**
* Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
* the first 10 terms will be:
* 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
* By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the
* even-valued terms.
*
* Result:
*/
object Problem2 {
def main(args: Array[String]): Unit = {
println("The result is " + fibbonaciNumbersSum(4000000))
}
// Why is it possible to call .scanLeft on an empty list (because it's empty in the moment we call it, right?)
lazy val fibbonaciNumbers: LazyList[Int] = 1 #:: fibbonaciNumbers.scanLeft(1)(_ + _)
private def fibbonaciNumbersSum(limit: Int) = fibbonaciNumbers.takeWhile(_ <= limit).filter(_ % 2 == 0).sum
}
LazyList 不为空。查看 Stream 的文档:
/** Construct a stream consisting of a given first element followed by elements
* from a lazily evaluated Stream.
*/
def #::[B >: A](hd: B): Stream[B] = cons(hd, tl)
所以至少你的 Stream/LazyList 有一个第一个元素(已评估)并且是
中的 11 #:: fibbonaciNumbers.scanLeft...
列表中的第二个元素是来自 scanLeft 的 1 ... 然后 scanLeft 接管以生成其余元素 2、3、5...但它们只会在以下情况下被评估需要。但是什么时候需要它们? ... 当你打电话给
println("The result is " + fibbonaciNumbersSum(4000000))
这将触发
的评估fibbonaciNumbers.takeWhile(_ <= limit).filter(_ % 2 == 0).sum
因此,只要 Stream / LazyList 中的每个元素小于限制,就会对其进行评估,并完成过滤和求和。