ストリーム (プログラミング)
「結果をn回求める」関数をrepeat、再帰関数をrecとしてその経過を見る。
repeatがrecを1度だけ呼び出す
recは再帰する直前の状態で一旦結果を返す
repeatは結果とともに、recを1回分だけ評価された関数(サンク。クロージャの一種)として受け取りリストに連結する
recを呼び出した回数がnでないなら、recをサンクの状態からフォース(強制評価)する
2から4を繰り返す
recの結果を返す
サンクは関数を評価した途中経過と見做せる。recを階乗関数factとして3回評価する場合のサンクの状態を(概念的にだが)示す。 fact関数は fact i = i * (fact i+1) と定義すればよい。
repeat 3 (fact 1)
repeat 3 (1 * fact 1+1)
repeat 3 (1 * 2 * fact 2+1)
repeat 3 (1 * 2 * 3 * fact 3+1)
---> 6
カッコの中全体がサンクと言える。また、フォースは「カッコの中と関数をひとつの関数として呼び出すこと」と言える。
遅延評価が標準である言語ではすべての再帰的な定義がストリームのように機能するため、とくにストリームと呼ぶことはない。しかしHaskellにおいては、モナドが導入される以前は、参照透過な入出力を実現するためのデータ構造をストリームと呼んでいた。
ストリーム(英: stream)とは、データを、比較的小さい単位が連続したものと捉え、上流から下流へ「流れるもの」とみなし、そのデータの入出力・送受信(途中段階を含む)を最小限の滞留とさせ低遅延処理となるように扱う形態を指す。またその操作のための抽象データ型を指す。
処理内部では適切なデータ分割・バッファリングが行われる。
入力ストリーム (input stream) を利用してデータの読み出しを行ない、出力ストリーム (output stream) を利用してデータの書き込みを行なう。対照的な概念としては、保管・永続化されたデータ形態(ファイル、データベースなど)がある。
メモリバッファの入出力を扱うもの、ネットワーク通信を扱うものなどさまざまなものがある。ファイルの入出力(読み書き)に対しては、ストリームとの変換を行う仕組みが用意される。
典型例として、Unixオペレーティングシステムおよびそのシェルによって実装されたものがある(標準ストリーム、パイプライン、リダイレクト)。