Railway-Oriented Programming
try/catchを使わず、失敗する可能性のある操作を連鎖させます。
「Railway-Oriented Programming」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。
鉄道のメタファー
レールウェイ指向プログラミングでは、計算を成功経路と失敗経路という2本の並行する線路として捉えます。いったん失敗側に切り替わると、その後はそこに留まり、残りの処理を飛ばします。
Result 関数を連鎖させる
各ステップは値を受け取り、Resultを返します。最初の失敗で連鎖を短絡し、その失敗を最後まで引き継ぐ形で、各ステップをつなぎたいと考えます。
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });
const err = <E>(error: E): Result<never, E> => ({ ok: false, error });map: 成功値を変換する
mapは、Resultが成功している場合に値へ通常の関数を適用し、失敗は変更せずにそのまま通します。成功経路に留まり続けます。
function map<T, U, E>(r: Result<T, E>, f: (t: T) => U): Result<U, E> {
return r.ok ? ok(f(r.value)) : r;
}
console.log(map(ok(2), n => n + 1)); // { ok: true, value: 3 }flatMap: 失敗するステップを連鎖させる
次のステップ自体がResultを返す場合は、flatMap(andThenとも呼ばれます)を使います。これによりResultの入れ子を避け、失敗時には連鎖を短絡できます。
function flatMap<T, U, E>(r: Result<T, E>, f: (t: T) => Result<U, E>): Result<U, E> {
return r.ok ? f(r.value) : r;
}map ではなく flatMap を使う理由
Resultを返す関数にmapを使うと、Result<Result<U,E>,E>になります。flatMapはそれを1段階平坦化し、Resultを1つに保ちます。
最初のエラーで短絡する
あるステップがerrを返すと、その後のすべてのflatMapはそれを変更せずに通します。失敗経路に切り替わる場合と同じように、残りのステップは実行されません。
const start = err("boom") as Result<number, string>;
const out = flatMap(start, n => ok(n + 1));
console.log(out); // { ok: false, error: "boom" }パイプラインを構築する
各ステップがResultを返すバリデーション処理を組み合わせます。最初の失敗がパイプラインの結果になり、すべて成功すれば成功した値が最後まで流れます。
function parseNum(s: string): Result<number, string> {
const n = Number(s);
return Number.isNaN(n) ? err("not a number") : ok(n);
}
function positive(n: number): Result<number, string> {
return n > 0 ? ok(n) : err("must be positive");
}パイプラインを実行する
flatMapを連鎖させると、値が失敗する可能性のある各ステップを順番に通過します。どこかで失敗すると連鎖が停止し、そのエラーが表面化します。
const good = flatMap(parseNum("5"), positive);
console.log(good); // { ok: true, value: 5 }
const bad = flatMap(parseNum("-3"), positive);
console.log(bad); // { ok: false, error: "must be positive" }map と flatMap を組み合わせる
失敗する可能性があるステップにはflatMapを、純粋な変換にはmapを使います。組み合わせることで、成功経路を直線的に保ちながら、エラーを自動的に処理できます。
const result = map(flatMap(parseNum("10"), positive), n => n * 2);
console.log(result); // { ok: true, value: 20 }try/catch は不要
パイプライン全体が、値によって成功と失敗を表現します。try/catchは必要なく、各ステップの型によってエラーの経路が明示され、避けられないものになります。
規模を拡大できる理由
レールウェイ指向のコードでは、複雑なワークフローも読みやすく保てます。各ステップは小さく純粋で、エラーは自動的に伝播し、ステップを追加しても既存のエラー処理が複雑になりません。
理解度チェック
このレッスンの理解度を確認します。
まとめ
レールウェイ指向プログラミングでは、Resultを返すステップを、map(成功を変換)とflatMap/andThen(失敗するステップを連鎖させ、入れ子になったResultを平坦化)でつなぎます。最初のerrが残りの処理を短絡し、try/catchなしで最後まで伝播します。
よくある質問
「Railway-Oriented Programming」レッスンは無料ですか?
はい。「Railway-Oriented Programming」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。
「Railway-Oriented Programming」で何を学びますか?
try/catchを使わず、失敗する可能性のある操作を連鎖させます。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「Railway-Oriented Programming」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- エラーをthrowすることの問題
- Result型のモデル化
- Option型とMaybe型
- Railway-Oriented Programming