このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

モニャドセミナー4の予定:トランザクション計算のフレームワークとか

モニャドセミナー4、今日の段階で参加予定者は14名。これからそんなに増えることもないでしょうから、十数名で開催となるでしょう。第4回ともなると、予想していた通り、参加者は「生き残り」メンバーという感じ。「初めての方も大歓迎」とか屈託なく言うのはさすがに躊躇<ためら>われます。とはいえ、第4回だけでも参加してみたいという方、そして既に参加を決めている人のために、モニャドセミナー4で予定している内容を紹介します。かなり詳しく書きますが、だからと言って、このとおりに実行される保証は全くないですからご注意/ご了承くださいませ。

実務者のための圏論モナド -- つう感じで

練習、質疑応答、議論を強調したいので、スライド利用講義風のスタイルはたぶん止めます。その代わり、印刷した資料*1を配付します。お絵描き&計算用のノートと筆記具は必須です。ホワイトボード2枚メイッパイ使うでしょう。

「クライスリ圏の話をするぞ」という予告は守るつもりです。が、今回は次のような疑問や疑念に応えることを主眼にしたいと思います。

  • こんなことを知って、なんか実務に役に立つの?
  • 絵算はどう使うの、ホントにありがたみがあるの?

実務上の煩雑さは削り落としますが、それでも単純すぎずリアリティが残る素材として、表題のような、トランザクション計算*2を組み合わせて実行するためのフレームワークを例題にします。処理が失敗した後のロールバック処理まで考えるのは面倒なので、それは割愛; 失敗に備えて、もとのデータを残したりロギングをするメカニズムを考えるのです。この題材は、今僕が興味を持っているトピックに近いものです。こういう話のほうがリアリティとかライブ感が出るのではないか、という目論見&魂胆です。

キュー&コミット・スタイルのトランザクション計算

取り扱う例題をここで紹介しておきます。

次のような状況を考えます; 計算処理(コンピュテーション)をする際に、外部環境(非ローカル変数、ファイル、データベースなど)を参照すること(読み取り)は自由にできるが、外部環境を直接変更することは許されてないとします。その代わり、当該の計算処理が完了したときに実行される予定の更新リクエストを発行できます。リクエストは発行順序を保ってキューに貯えられます*3。計算処理が無事に終わると、キューイングされた更新リクエストが順に実行され、外部環境は変更されます -- 正確に言うと、あたかも変更されたように振る舞います。

以上のような処理に対して、外部環境は暗黙に与えられますが、処理ごとに明示的に渡すパラメータがあってもかまいません。また、計算結果は戻り値として返せます。環境の更新は副作用と考えられます。2つの計算処理をつないだものをトランザクションとみなす場合を考えると、1つめの処理の直後でホントに環境に変更を加えると、2つ目の処理が失敗したときに初期状態を復元できないかもしれません。実際のコミットは、計算処理全体がホントに終わったときに行うべきで、部分計算に対するコミットは仮のコミットとなります。

ひとつ注意しておくと、「直接に外部環境を変更することは許されてない」というのは、外から見たときの話で、計算処理を実行する主体*4は「許されている/許されてない」などを知っているわけじゃありません。リクエスト発行を変更と認識しても問題はありません。ただ、変更しても参照している元データへの即時反映が行われない点には注意が必要ですけども。

圏論モナドをどう使うのか

副作用としての書き込み(メモリ/ストレージの更新)はモノイダル・スタンピング・モナドで定式化して、外部環境の参照(読み取り)は、その双対であるコモノイダル・スタンピング・コモナドを使って定式化します。書き込みのコミット操作は、モノイド作用(線形代数の用語では加群)で定式化します。計算処理の逐次実行は、クライスリ結合、余クライスリ結合、両クライスリ結合となります。

[追記]以下の段落で「半関手」という言葉はまったく不適切でした。訂正と補足をご覧ください。[/追記]

クライスリ圏、余クライスリ圏、両クライスリ圏の計算では、ラッピング半関手を使う方法を紹介しましょう。半関手(semi-functor)とは、結合は保存するが恒等の保存が保証されない対応です。「ラッピング」は僕がでっち上げた形容詞ですが、Adapterデザインパターンとか、あんな感じ*5。結合機構(コンポジション・マシナリ)の一部を、射に押しつける技法ですね。ラッピング半関手により、計算は(絵算も等式計算も)だいぶ楽になります。

なんか難しげ? 大丈夫、ここで絵算が威力を発揮するはず。絵に描けば難しそうな概念もクリアになります。本来、モナドの取り扱いは自然変換の計算になりますが、モノイダル・スタンピング・モナドに限れば、射の変形操作(ワイヤリング)だけでだいたい済みます。まー、モニャドセミナー3で自然変換を飛ばしちまった都合で、自然変換なしで済ませたいという事情もあります。

モノイダル・スタンピング・モナドに限定して、自然変換を正面から取り上げないことは、絵算を矮小化することになりますが、それでも絵算の威力と醍醐味はある程度は伝わるんじゃないのかなー、と思ってます。

*1:カタカナだと、レジュメ、アジェンダシラバスとかいうんでしょうか。

*2:環境へのインパクトをキチンと制御して、好きなだけ汚染(破壊的変更)を遅延できるような計算なので、エコ計算と呼んだほうが実情を表しているかも。

*3:一般論で言えば、リクエストは必ずしもキューイングされる必要はなくて、なんらかの意味で累積されます。

*4:フレームワークに対してプラッガブルな何者かです。コンポネント、プロセス、タスク、エージェント、コマンド、… まーお好きなように呼んでください。

*5:Adapterパターンの別名がWrapperパターン。