简体   繁体   中英

Lazy stream does not work

I'm using Stream to create a lazy sequence. My sequence is combined from others sequences by ++. But my code does not work. Why?

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)

your failure can be much simplified:

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

I'm taking into account that your select function is nothing more than map.

map/flatMap for a Stream will strictly evaluate the head of the stream but not the tail of the stream when the tail is lazy. so here, we are mapping on a single element stream and or proxy function is evaluated the one time.

So, since you are mapping on the single element streams BEFORE you append them to the stream you are accumulating, you will see your proxy function being called each time.

try this one:

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

and you'll find that the assertion holds. The head of our stream is strictly mapped, but the tail of the stream hasn't been evaluated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM