While trying to understand the differences between streams, iterators, and collection views, I came across the following strange behavior.
Here is the code (the card and the filter simply print their input and forward without changes):
object ArrayViewTest {
def main(args: Array[String]) {
val array = Array.range(1,10)
print("stream-map-head: ")
array.toStream.map(x => {print(x); x}).head
print("\nstream-filter-head: ")
array.toStream.filter(x => {print(x); true}).head
print("\niterator-map-head: ")
array.iterator.map(x => {print(x); x}).take(1).toArray
print("\niterator-filter-head: ")
array.iterator.filter(x => {print(x); true}).take(1).toArray
print("\nview-map-head: ")
array.view.map(x => {print(x); x}).head
print("\nview-filter-head: ")
array.view.filter(x => {print(x); true}).head
}
}
And his conclusion:
stream-map-head: 1
stream-filter-head: 1
iterator-map-head: 1
iterator-filter-head: 1
view-map-head: 1
view-filter-head: 123456789 // <------ WHY ?
Why does the filter invoke the process of viewing the entire array? I expected that the filter evaluation is controlled only once, causing the head, as in all other cases, in particular, the same as when using the card in sight.
What insight am I missing?
(question about the mini-side for comment, why there is no head on the iterator?)
( scala.Array.range(1,10)) scala.collection.mutable.ArraySeq.range(1,10), scala.collection.mutable.ArrayBuffer.range(1,10) scala.collection.mutable.StringBuilder.newBuilder.append("123456789").
, , 1.