This is what happens. When you define an iterator in a Scala REPL, some information about this iterator is printed, whether empty or not in particular:
scala> Iterator.continually(List(1)).flatten
res1: Iterator[Int] = non-empty iterator
This information is returned by a method toString Iteratorthat is defined as follows:
override def toString = (if (hasNext) "non-empty" else "empty")+" iterator"
Basically, hasNextcalled for a newly created iterator. Now let's see what hasNext( scala.collection.TraversableOnce.FlattenOps#flatten) does in your case :
class FlattenOps[A](travs: TraversableOnce[TraversableOnce[A]]) {
def flatten: Iterator[A] = new AbstractIterator[A] {
val its = travs.toIterator
private var it: Iterator[A] = Iterator.empty
def hasNext: Boolean = it.hasNext || its.hasNext && { it = its.next().toIterator; hasNext }
def next(): A = if (hasNext) it.next() else Iterator.empty.next()
}
}
! hasNext , , . , . , , REPL. StackOverflow, , Scala while.