Scalas (a, b) .zipped (или Tuple2.zipped) понятие с использованием потоков / бесконечных списков - PullRequest
6 голосов
/ 11 марта 2011

вот то, что я думал, было бы правильным и полезным определением чисел Фибоначчи в scala:

lazy val fibs:Stream[Int] = 0 #:: 1 #:: (fibs,fibs.tail).zipped.map(_+_)

Однако я получаю следующую ошибку:

fibs take 10 foreach println
0
1
java.lang.StackOverflowError
    at scala.collection.mutable.LazyBuilder.(LazyBuilder.scala:25)
    at scala.collection.immutable.Stream$StreamBuilder.(Stream.scala:492)
    at scala.collection.immutable.Stream$.newBuilder(Stream.scala:483)
    at...

Я думаю, молниине работает правильно с потоками?Любые предложения о том, как заставить это работать, или почему это не (не должно?) Работать?

Ответы [ 2 ]

8 голосов
/ 11 марта 2011

Следующее работает правильно

val fibs:Stream[Int] = 0 #:: 1 #:: (fibs zip fibs.tail).map{ case (a,b) => a+b }

Проблема с Tuple2.zipped заключается в том, что он предполагает, что он может запускать foreach на последовательностях, которые он архивирует. Вероятно, это сделано по замыслу, так как выполнение того, что реализует Stream.zip, могло бы дать вам плохую производительность для любого Seq конечной длины, который не является List или Stream. (Поскольку большинство структур данных не поддерживают эффективную реализацию tail.)


Stream.zip по существу реализован следующим образом (хотя он делает некоторые вещи, чтобы сделать типы более общими). ​​

class Stream[A]{
  def zip(other:Stream[B]) =
    (this.head, other.head) #:: (this.tail zip other.tail)
}
3 голосов
/ 12 марта 2011

В базе данных Scala Trac есть билет: http://lampsvn.epfl.ch/trac/scala/ticket/2634

Билет был закрыт как wontfix, но обратите внимание на Адриана "Или мы что-то упустили?" в комментариях - возможно, это когда-нибудь будет пересмотрено.

...