Почему TraversableOnce.toSeq возвращает поток?

Вот пример:

scala> val xs = List(1,2,3).toIterator.toSeq
xs: Seq[Int] = Stream(1, ?)

Последовательность - это материализованная коллекция (по умолчанию это List), поэтому я ожидал, что toSeq вернет List, а не Stream

Реализация находится в TraversableOnce,

  def toSeq: Seq[A] = toStream

почему он не отменяется в TraversableLike?


person Adrian    schedule 17.10.2014    source источник
comment
Поскольку нет необходимости использовать итератор для получения действительного Seq, зачем вам это? Всегда есть toList, toVector и т. Д., Если они вам действительно нужны.   -  person Travis Brown    schedule 17.10.2014
comment
Кроме того, вам действительно следует просто притвориться, что вы не знаете, что базовая реализация возвращаемого Seq - это Stream. Если вам интересно, используйте другой toX метод.   -  person Travis Brown    schedule 17.10.2014
comment
Трэвис, у вас может быть такой же аргумент для toIndexedSeq (). IndexedSeq - это тоже черта, как и Seq. List (1,2,3) .toIterator.toIndexedSeq возвращает вектор, который является реализацией IndexedSeq по умолчанию. Я согласен с тем, что List (1,2,3) .toIterator.toSeq, возвращающий List, может быть слишком специализированным, но я думаю, что сохранение правильной семантики будет более важным.   -  person Adrian    schedule 18.10.2014
comment
Но невозможно написать действительную реализацию IndexedSeq, которая не требует использования итератора. На самом деле нет какой-либо реализации по умолчанию для Seq или IndexedSeq - есть тот, который возвращается apply для сопутствующего объекта, но это не какой-то особый статус. Кроме того, сведения о том, какой подтип используется, конечно, статически недоступны и могут быть изменены.   -  person Travis Brown    schedule 18.10.2014
comment
Также невозможно написать действительную реализацию Seq, которая не требует использования итератора. Так почему же у toSeq и toIndexedSeq разная семантика? С другой стороны, в нашем случае iterator.toSeq возвращает Stream. Почему именно стрим?   -  person Adrian    schedule 18.10.2014
comment
Но Stream не должен использовать итератор, и это Seq. Контракт IndexedSeq требует постоянного доступа по индексу, что означает, что нам нужно вытащить все элементы из итератора.   -  person Travis Brown    schedule 18.10.2014
comment
В любом случае мы на самом деле не говорим о семантике toSeq и toIndexedSeq - она ​​полностью улавливается их возвращаемыми типами. Речь идет о деталях реализации.   -  person Travis Brown    schedule 18.10.2014
comment
Трэвис, имеет смысл. Я не понимал, что Stream - это Seq. Поток не отображается в изображениях дерева иерархии типов коллекции scala ...   -  person Adrian    schedule 18.10.2014


Ответы (1)


Scala поддерживает бесконечные итераторы, а Stream - простейший Seq для возможных бесконечных данных.

Iterator.from(1).toSeq

завершается (если используется только часть коллекции), но

Iterator.from(1).toList

никогда не прекратится.

Вы не хотите делать код взлома, если не будет равнозначного решения. Метод toSeq не знает источника итератора, поэтому он должен предполагать, что он может быть бесконечным.

Документы "объясняют" это решение так:

Преобразует этот обход или итератор в последовательность. Как и в случае с toIterable, в этой реализации по умолчанию он ленив, так как TraversableOnce может быть ленивым и невычисленным. Примечание: не прекращается для коллекций бесконечного размера.

http://www.scala-lang.org/api/current/?_ga=1.200291566.1390086478.1406220121#scala.collection.Iterator

person bmaderbacher    schedule 17.10.2014
comment
Iterator.form(1) создает бесконечную последовательность, представляющую натуральные числа - person bmaderbacher; 18.10.2014
comment
Верно. Stream - это простейший Seq, даже если это не очевидно, он все объясняет. - person Adrian; 18.10.2014