惰性流不能工作



我使用Stream来创建一个延迟序列。我的序列是用++和其他序列组合起来的。但是我的代码不工作。为什么?

def select[T1, T2](s: Stream[T1], map: T1=>T2): Stream[T2] = {
    for (sv <- s) yield map(sv)
}
var innerCounter = 0
var proxy = (x: Int) => { innerCounter += 1; x }
var list: Stream[Int] = select[Int,Int](Stream.empty, k => k)
for (nc <- 0 until 10) {
     list = select[Int,Int](Stream.empty, k => k)
     var i: Int = 0
      while (i < CountConcat) {
          i += 1
          list = list ++ select[Int,Int](Stream(0), k => proxy(i + 100))
       }
}
assert(innerCounter == 0)

你的失败可以简化得多:

var innerCounter = 0
val proxy = (x: Int) => { innerCounter += 1; x }
Stream(0).map(k => proxy(100))
assert(innerCounter == 0)

我考虑到你的select函数只不过是map。

流的

map/flatMap将严格计算流的头部,而不是流的尾部,如果尾部是惰性的。因此,在这里,我们是在单个元素流上进行映射,并且代理函数只计算一次。

所以,因为你是在单个元素流上进行映射的,在你将它们附加到你正在累积的流上之前,你会看到你的代理函数每次都被调用。

试试这个:

var innerCounter = 0
val proxy = (x: Int) => { innerCounter += 1; x }
(Stream.empty ++ Stream(0) ++ Stream(1)).map(k => proxy(100))
 assert(innerCounter == 1)

,你会发现断言成立。流的头部是严格映射的,但流的尾部没有求值。

相关内容

  • 没有找到相关文章

最新更新