ジムビームはあるかもしれないし、そうでないかもしれない 〜あるいは TypeScript で Maybe を do する〜
バーのカウンターに肘をつきながら、僕はグラスの中の琥珀色の液体を眺めていた。
それはまるで、遠い昔の記憶の断片が液体の形を取ったかのように、静かに揺れていた。
「ジムビームはある?」
僕はそう尋ねた。
バーテンダーは、静かに瓶を手に取り、カウンターの上に置いた。
そこにジムビームは「ある」。
しかし、それが本当に「ある」と言えるのかどうかは、
哲学的な問いのようにも思えた。
TypeScriptの世界にも、こんなふうに曖昧な存在を扱う仕組みがある。
それが、F-Box の Maybeだ。
Maybeは、あるかもしれないし、ないかもしれない。
それは、ジムビームがカウンターに置かれていることと、
それを飲んで初めて「確かにあった」と実感することの違いのようなものかもしれない。
やれやれ。
僕たちはそんなものをTypeScriptで扱わなければならないらしい。
Maybeという箱
現実の世界では、
僕たちはしばしば次のような状況に出会う。
const drink: string | null = getDrink();
この drink
に、値がちゃんと入っているかどうかは、
誰にも確証がない。
値があるかもしれないし、ないかもしれない。
TypeScriptの世界で、
この曖昧な状態をそのまま抱え込むために、
F-BoxのMaybeという箱があるのだ。
例えば、ジムビームについて考えてみよう。
以下は、ジムビームが存在するかどうかを決める、
シュレーディンガー的な関数だ。
import { Maybe } from "f-box-core";
const getMaybeDrink = (): Maybe<string> => {
return Math.random() > 0.5
? Maybe.pack("Jim Beam")
: Maybe.nothing();
};
この getMaybeDrink()
は、
ジムビームがあるかもしれないし、
ないかもしれない。
棚に瓶が残っているか、バーテンダーが確かめる前の、
不確かな状態そのものだ。
Maybeをdoする
バーのカウンターで、
僕は静かに時の流れを待っていた。
グラスの中の氷がゆっくりと溶ける音に耳を澄ませながら、
do
という構文を使って、
Maybeの箱から値を取り出すという処理ができることを思い出す。
const orderDrink = () =>
Maybe.do<string, string>(function* () {
const drink = yield getMaybeDrink();
return `バーテンダーは静かにグラスを磨き、${drink}を注いだ。`;
});
このコードは、
もし getMaybeDrink()
がジムビームを返してくれたなら、
その値を用いて、
バーテンダーが迷いなくグラスに注ぐシーンを再現する。
しかし、もし箱が空なら、
物語はそこで途切れてしまう。
そして、その結果は次のように確認される。
const barScene = orderDrink();
console.log(barScene.getOrElse("その夜、ジムビームはなかった。"));
もしグラスが満たされていなければ、
「その夜、ジムビームはなかった。」
という現実が、静かに画面に映し出される。
ジムビームがない夜
バーテンダーは棚をもう一度見渡し、
ひとつ息をついた。
「申し訳ありません。ジムビームは切らしていまして」と、
寂しげに告げる。
そんな夜も、確かに存在する。
getMaybeDrink()
が Maybe.nothing()
を返す可能性があるように、
僕たちの夜には、ジムビームが届かない瞬間があるのだ。
現実はただ、確率の問題だ。
グラスに何も注がれなければ、
それはただ「何もない」という事実として、
心にそっと刻まれる。
夜の終わりに
バーを後にすると、
夜の空気はひどく冷たく、
遠くのネオンがぼんやりと揺れていた。
僕はコートのポケットに手を突っ込みながら、
足早に通りを歩いた。
Maybeという箱は、
現実の曖昧さをそのまま映し出す鏡のようだ。
そこにジムビームがあるかもしれないし、
あるいは、そうでないかもしれない。
どちらの真実も、
この街のどこかで、
今も静かに続いている物語のひとつに過ぎないのだ。
やれやれ、
今日もまた、
存在するかもしれないし、
存在しないかもしれないジムビームと共に、
夜は淡々と流れていく。
Discussion