2011-03-11 11 views
6

ストリーム/無限リストを使用して概念は、私はスカラ座でのフィボナッチNUMSの正確かつ有用な定義だろうと思ったものです:Scalas(a、b)は.zipped(またはTuple2.zipped)ここ

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... 

ストリームで正しく圧縮されていないようですか?どのようにこの作品を作るか、あるいはこれがなぜ成果を上げないのかについての提案はありますか?

+0

私はちょうどこの_exact_質問をするつもりでした。私の前に誰かがここにいるのを知って冷たい。 +1 – KChaloux

答えて

8

次の作品は正しく

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

Tuple2.zippedの問題は、それはそれはそれはビュンだ配列にforeachを実行できると仮定していることです。 Stream.zipの実装では、またはStream以外の有限長のSeqに対しては、おそらくパフォーマンスが悪くなるため、これはおそらく設計によるものです。 (最もデータ構造はtailの効率的な実装をサポートしていませんので。)


Stream.zipは、基本的に(それはタイプは、より一般的にするためにいくつかのものを行いますが)次のように実装されています。 ScalaのTracのデータベースでは、この上のチケットがあります

class Stream[A]{ 
    def zip(other:Stream[B]) = 
    (this.head, other.head) #:: (this.tail zip other.tail) 
} 
+0

あなたの質問の 'lazy'修飾子は不要ですが、私の答えでそれを削除することは、この作業をしたものではありませんでした。 –

+0

さて、あなたが見せてくれたことはとてもいいです:)これは、haskellのように引数として2-arity関数を取る "zipWith"がどれくらい必要かを示すためにしかないと思います。私は本当になぜそれがスカラにないのか分からないのですか? – Felix

+1

@Felix: 'zipWith'がどのように役立つのか分かりません。タプル上の 'zipWith'は、最初のリストが無限ストリームだったときにオーバーフローする' foreach'として実装されます。 –

3

http://lampsvn.epfl.ch/trac/scala/ticket/2634チケットがWONTFIXとして閉じ、しかしアドリアンの留意た

「それとも私たちは何かが欠けているの?」コメントで - これはいつか再訪されます。

関連する問題