ストリーム | 目次 |
最新版は Scala Documentation に移行しました。
ストリーム (Stream) はリストに似ているが、要素は遅延評価される。そのため、ストリームは無限の長さをもつことができる。呼び出された要素のみが計算される。他の点においては、ストリームはリストと同じ性能特性をもつ。
リストは :: 演算子によって構築されるが、ストリームはそれに似た #:: 演算子によって構築される。以下は、整数の 1, 2, 3 からなる簡単なストリームの例だ:
scala> val str = 1 #:: 2 #:: 3 #:: Stream.empty | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
str: scala.collection.immutable.Stream[Int] = Stream(1, ?) |
このストリームの head は 1 で、tail は 2 と 3 だ。上の例では tail が表示されていないが、それはまだ計算されていないからだ。ストリームは遅延評価されるため、toString は余計な評価を強いないように慎重に設計されているのだ。
以下に、もう少し複雑な例を示す。任意の二つの数から始まるフィボナッチ数列を計算するストリームだ。フィボナッチ数列とは、それぞれの要素がその前二つの要素の和である数列のことだ。
scala> def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
a + b) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fibFrom: (a: Int,b: Int)Stream[Int] |
この関数は嘘のように単純だ。数列の最初の要素は明らかに a で、残りは b そして a + b から始まるフィボナッチ数列だ。無限の再帰呼び出しに陥らずにこの数列を計算するのが難しい所だ。もしこの関数が #:: の代わりに :: を使っていたなら、全ての呼び出しはまた別の呼び出しを招くため、無限の再帰呼び出しに陥ってしまう。しかし、#:: を使っているため、右辺は呼び出されるまでは評価されないのだ。
二つの 1 から始まるフィボナッチ数列の最初の数要素を以下に示す:
scala> val fibs = fibFrom(1, 1).take(7) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fibs: scala.collection.immutable.Stream[Int] = Stream(1, ?) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
scala> fibs.toList | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res9: List[Int] = List(1, 1, 2, 3, 5, 8, 11) |
続いては、ベクトル
ストリーム | 目次 |