我使用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)
答案 0 :(得分:1)
你的失败可以简化:
var innerCounter = 0
val proxy = (x: Int) => { innerCounter += 1; x }
Stream(0).map(k => proxy(100))
assert(innerCounter == 0)
我考虑到你的选择功能只不过是map。
用于Stream的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)
你会发现断言成立。我们的流的头部是严格映射的,但是流的尾部尚未被评估。