TL;DR
ジェネレータ関数を使って、async / await に近い書き方で Effect を組み立てる関数。
なぜ必要か
pipe で処理を組み立てると、ステップが増えるにつれて読みにくくなる。
const main = fetchRequest.pipe(
Effect.filterOrFail(
(response) => response.ok,
(): FetchError => new FetchError(),
),
Effect.flatMap(jsonResponse),
Effect.catchTags({
FetchError: () => Effect.succeed("Fetch error"),
JsonError: () => Effect.succeed("Json error"),
}),
)Effect.gen を使うと、普段の TypeScript の構文に近い形で書ける。
const main = Effect.gen(function* () {
const response = yield* fetchRequest
if (!response.ok) return yield* new FetchError()
return yield* jsonResponse(response)
})仕組み
上のコードは、async / await のコードを次のように置き換えたものに近い。
asyncをEffect.genにする- 無名関数をジェネレータ関数にする
awaitとthrowをyield*にする
const main = async () => {
const response = await fetchRequest()
if (!response.ok) throw new FetchError()
return await jsonResponse(response)
}Effect.gen は、JavaScript のジェネレータとイテレータのプロトコルを組み合わせて、関数内の各ステップの成功やエラーを追跡している。