uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

Java8のStreamでフィボナッチ数を計算する

フィボナッチ数ってあるじゃないですか。
Java8のStreamを使って書いてみます。Groovyで。

import static java.util.stream.Collectors.*
import java.util.stream.*

println Stream.iterate([1l, 1l]) {
    (old1, old2) = it
    [old1+old2, old1]
}.map{it[1]}.limit(10).collect(toList())

こんな感じですか。10個のフィボナッチ数を表示します。
無限ストリームなんかを作っちゃっています。

% groovy fib.groovy
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

調べると、streamてのは本質的にはIteratorフレームワークですな。
目的は並列処理うんぬんが主眼かもしれませんが、機構としてはIterator(Spliterator)のチェインをフルーエントなビルダーで作って、ケツのところでぶん回す、というものです。遅延リストとは違うし遅延評価とも関係ない*1。制約が多くてそれがおもしろい。別に記事書くかも。

*1:ごく広義の遅延評価とは言えるかもしれないが、広義すぎて何も言ってないのと同じmapやfilterなどで作る中間ストリームに与えたラムダ式が遅延実行される、という意味で遅延評価とは言える。それほど特別なシチュエーションではないと思うが、通常のforEachとかリースパターンと比べると遅延ではある。