ストリーム | 目次 |
ストリーム(Stream)はリストに似ていますが、要素を遅延的に計算します。 そのため、ストリームは無限の長さを持つ場合もあります。 要求された要素のみが計算されます。 その点を除いてストリームはリストと同じ性能特性を持ちます。
リストが::演算子で構築されるのに対して、ストリームは良く似た形状の#::で構築されます。 これは整数1, 2および3を含むストリームの簡単な例です:
scala> val str = 1 #:: 2 #:: 3 #:: Stream.empty
str: scala.collection.immutable.Stream[Int] = Stream(1, ?)
ストリームの先頭は1で、その尾は2と3を備えます。 しかし尾はまだ計算されていないためここでは表示されません。 ストリームは遅延的に計算するように定められており、ストリームのtoStringメソッドは余分な評価を強要しないように注意しています。
以下はさらに複雑な例です。 これは与えられた2つの数から始まるフィボナッチ列を含むストリームを計算します。 フィボナッチ列は各要素がその前の2つの要素の和であるような列です。
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が続くフィボナッチ列です。 トリッキーなのはこの列を無限再帰を起さずに計算するところです。 もし#::の代わりに::を使ったとすると、この関数呼び出しは必ず別の呼び出しを引き起し、つまり無限再帰を起します。 しかし#::を使っているため、右辺は必要になるまで評価されません。
これは2つの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)
続いては: ベクタ
ストリーム | 目次 |