Почему комбинации методов возвращают Iterator, а не Stream в Scala?

Я заметил этот метод combinations (из здесь ) возвращает Iterator. Кажется разумным, что метод должен быть ленивым, чтобы избежать генерирования всех комбинаций заранее. Теперь мне интересно, почему он возвращает Iterator вместо Stream (это ленивый список в Scala).

Итак, почему combinations возвращает Iterator, а не Stream?


person Michael    schedule 02.12.2011    source источник


Ответы (4)


С Stream более вероятно, что все сгенерированные значения будут храниться в памяти.

scala> val s = Stream.iterate(0)(_ + 1)
s: scala.collection.immutable.Stream[Int] = Stream(0, ?)

scala> s.drop(3).head
res1: Int = 3

scala> s
res2: scala.collection.immutable.Stream[Int] = Stream(0, 1, 2, 3, ?)

Когда вы сохраните ссылку на свой Stream, все сгенерированные элементы останутся в памяти. С Iterator это менее вероятно.

Конечно, это не должно быть причиной того, что библиотека Scala спроектирована именно так...

person ziggystar    schedule 02.12.2011

Я думаю, потому что Stream кэширует все ранее возвращенные элементы, поэтому в конечном итоге все они будут в памяти. Итератор возвращает только следующий

person The Archetypal Paul    schedule 02.12.2011

Как я вижу в коде CombinationsItr, у вас есть ленивая оценка каждый раз, когда вы вызываете метод next. См. https ://lampsvn.epfl.ch/trac/scala/browser/scala/tags/Rnext9CombinationsItrfinal/src//library/scala/collection/SeqLike.scala#L198

Итак, при использовании next для получения следующей комбинации, например:

scala> val combinations = "azertyuiop".combinations(2)
scala> combinations.next
res9: String = az

результат next оценивается лениво.

person David    schedule 02.12.2011
comment
Означает ли это, что вы можете отказаться от итератора, не создавая промежуточных значений? - person ziggystar; 02.12.2011
comment
Это интересный вопрос, как видно из кода Iterator (lampsvn.epfl.ch/trac/scala/browser/scala/tags/Rdrop9Iteratorfinal/src/), метод drop вернет новый экземпляр Iterator, который ссылайтесь на предыдущий (где вы вызываете drop). Это означает, что даже отброшенная версия Iterator будет оцениваться лениво (но будет содержать собственный счетчик remaining). - person David; 02.12.2011

Iterator дешевле, чем Stream. Вы всегда можете получить последнее из первого, если вам нужно.

person Daniel C. Sobral    schedule 04.12.2011