2011-12-15 12 views
5

実行:私が期待するScalaのストリーム混乱

lazy val s: Stream[Int] = 1 #:: 2 #:: {val x = s.tail.map(_+1); println("> " + x.head); x} 
s.take(5).toList 

> List(2, 3) 
> List(2, 3, 4) 
List(1, 2, 3, 4, 5) 

そして私が手:

> 3 
List(1, 2, 3, 4, 5) 

あなたは私にそれを説明してもらえますか?

+2

なぜ 'x.head'がリストを返すと思いますか? – sepp2k

+0

私が混乱しているのは、なぜ、怠惰なvalの定義の中に 'println'を置くのが良いのかということです。 –

+2

@Dan:式が実行される時期と頻度(そしてそのときのさまざまな値がどのようになるか)を知るために、私は想像しています。 – sepp2k

答えて

5

Listの代わりにIntが表示される理由は、sが整数のストリームなので、リストではなく整数が含まれているためです。

あなたが3を得る理由は、(1,2,3,4,5、...)(すなわちs)の尾が(2,3,4,5、...)であり、ifその上に+1を置くと、(3,4,5,6,7、...)が得られ、その頭部は3です。

1つの整数だけが印刷される理由は、式がテールのストリームを取得するために一度しか評価されません。その後、s.tail.map(_+1)によって返されたストリームのみが評価されます(これにはprintステートメントは含まれません)。

+0

これを考慮してください: 'val s:Stream [Int] = 1#:: 2#:: {val x = s.tail.map(1+); xは10枚の印刷物を取る。 x}は '3333 ...'を出力して落ちるので、 'x'は3,4,5ではなく3つのストリームのように見えますが、' s'は 'ストリーム(1,2,3,3,3、...) '。私はとても混乱しています、私はストリームについてもっと読むことができるアドバイスはありますか? – 4e6

+0

@ 4e6:ストリームを生成する式の中で生成されたものより多くのストリーム要素を消費すると、無限の再帰が発生します(最終的にスタックを爆発させます)。あなたが非常に多くの3を得る理由は、ストリームにはその数が3つ含まれているのではなく(コンマで区切られていれば)、printステートメントが何度も実行されるということです(論理が円で再帰し、 printステートメントを何度も繰り返して...)。 – sepp2k

+0

@ 4e6あなたが書いたことを考えてみましょう:3番目の数字を計算するには、10番目の数字を印刷する必要があります。しかし、それがまだ計算されていなければ、3番目の数字をどのように印刷できますか?それは間違いです。 –