Here is a concrete example:
def eleventh[A](xs: Iterator[A]) = { xs.take(10).toList xs.next }
We can try:
scala> eleventh((1 to 100).toList.toIterator) res0: Int = 11 scala> eleventh((1 to 100).toStream.toIterator) res1: Int = 11 scala> eleventh(Stream.from(1).toIterator) res2: Int = 11
Looks nice. But then:
scala> eleventh((1 to 100).toIterator) res3: Int = 1
Now (1 to 100).toIterator is of the same type as (1 to 100).toList.toIterator , but they behave very differently here - we see that implementation details flow from the API. This is very bad, and it is the direct result of mixing purely functional combinators like take with an inherently imperative and mutable concept such as an iterator.
source share