ストリーム入門
このガイドでは、Stream<A, E, R>という概念を探っていきます。Streamはプログラムの記述であり、実行時にタイプAの0 個以上の値を出力し、タイプEのエラーを処理し、タイプRのコンテキスト内で操作します。
用途
ストリームは、時間の経過に伴う値のシーケンスを扱う際に特に便利です。オブザーバブル、ノードストリーム、AsyncIterable の代替として機能することができます。
ストリームとは?
StreamはEffectの拡張として考えてみてください。Effect<A, E, R>は、タイプRのコンテキストを必要とし、タイプEのエラーが発生する可能性があり、タイプAの単一の結果を常に生成するプログラムを表しますが、Stream<A, E, R>はこれをさらに進め、タイプAの 0 個以上の値を出力できるようにします。
具体的に説明するため、いくつかのEffectの例を見てみましょう。
import { Effect, Chunk, Option } from "effect";
// 文字列エラーで失敗するEffectconst failedEffect = Effect.fail("fail!");
// 単一の数値を生成するEffectconst oneNumberValue = Effect.succeed(3);
// 数値のチャンクを生成するEffectconst oneListValue = Effect.succeed(Chunk.make(1, 2, 3));
// オプショナルな数値を生成するEffectconst oneOption = Effect.succeed(Option.some(1));このいずれの場合も、Effectは常に正確に 1 つの値で終了します。結果に変動はありません。常に 1 つの結果が得られます。
ストリームの理解
さて、焦点をStreamに移しましょう。StreamはEffectに似たプログラムの記述を表し、タイプRのコンテキストを必要とし、タイプEのエラーを示す可能性があり、タイプAの値を生成します。しかし、重要な違いは、0 個以上の値を生成できる点です。
Streamの考えられるシナリオは次のとおりです。
- 空のストリーム: 値を持たないストリームになる可能性があります。
- 単一要素のストリーム: 1 つの値のみを持つストリームを表すことができます。
- 有限要素のストリーム: 限定された数の値を持つストリームを表します。
- 無限要素のストリーム: 無限に続くストリームを表すことができ、本質的には無限ストリームです。
これらのシナリオを見てみましょう。
import { Stream } from "effect";
// 空のストリームconst emptyStream = Stream.empty;
// 単一の数値を持つストリームconst oneNumberValueStream = Stream.succeed(3);
// 1から10までの数値の範囲を持つストリームconst finiteNumberStream = Stream.range(1, 10);
// 1から始まり加算していく無限数値のストリームconst infiniteNumberStream = Stream.iterate(1, (n) => n + 1);まとめると、Streamは複数の値を出力できるプログラムを表現するための柔軟なツールであり、有限リストの処理から無限シーケンスの処理に至るまで、さまざまなタスクに適したものです。