1

我有一个无限的流,自然需要从中“拉”到某个元素。这是第一步。但是只有部分“拉”的元素将在第二步中使用,例如只有偶数元素。是否可以通过惰性来避免处理奇数元素?

解释我要问的更好的方法是显示代码:

  Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
  Type in expressions to have them evaluated.
  Type :help for more information.

  scala> var n=0; def numbers:Stream[Int] = {n += 1; println("n= " + n); n #:: numbers}
  n: Int = 0
  numbers: Stream[Int]

  scala> numbers.map{z => println("z^2= " + z*z) ; z*z}.take(10)(2)
  n= 1
  z^2= 1
  n= 2
  z^2= 4
  n= 3
  z^2= 9
  res0: Int = 9

  scala> var n=0; def numbers:Stream[Int] = {n += 1; println("n= " + n); n #:: numbers}
  n: Int = 0
  numbers: Stream[Int]

  scala> numbers.map{lazy z => println("z^2= " + z*z) ; z}.take(10)(2)
  <console>:1: error: lazy not allowed here. Only vals can be lazy
  numbers.map{lazy z => println("z^2= " + z*z) ; z*z}.take(10)(2)
  ^

  scala> 

由于take(10)(2)is的结果,因此res0: Int = 9z^2= 9需要计算。

4

1 回答 1

2

如果你想推迟z^2map操作)的计算, aview应该足够了:

object Worksheet {
  var n = 0                                   //> n  : Int = 0
  def numbers: Stream[Int] = { n += 1; println("n= " + n); n #:: numbers }
                                              //> numbers: => Stream[Int]

  numbers.view.map { z => println("z^2= " + z * z); z }.take(10)(2)
                                              //> n= 1
                                              //| n= 2
                                              //| n= 3
                                              //| z^2= 9
                                              //| res0: Int = 3
}

如果您还想将流中数字的生成推迟到需要它们时,您可以手动执行此操作:

object sheet {
  var n = 0                                   //> n  : Int = 0
  def numbers: Stream[() => Int] = (() => { n += 1; println("n= " + n); n }) #:: numbers
                                              //> numbers: => Stream[() => Int]

  numbers.view.map { z => val x = z(); println("z^2= " + x * x); x }.take(10)(2)
                                              //> n= 1
                                              //| z^2= 1
                                              //| res0: Int = 1
}

这里的问题似乎是 Scala 库中的流并不懒惰。如果 Scalaz 库已经有类似的东西,我不会感到惊讶。

于 2013-01-22T06:38:49.550 回答