Arantium Maestum

プログラミング、囲碁、読書の話題

Monadic Reflectionについて

kontlang作成の一つの目標は、この資料を元に:

www.slideshare.net

モナドをつくれるようにしてみたい、というものだった。

結果的にMaybe、ListやStateモナドを「つくって」みたのだが。

そもそもこのつくったものは本当にモナドなのか?という疑問が湧いてきた。

挙動はHaskelldo記法に非常に近いが、微妙に違いもあるし、そもそもモナドとはreturnbindがあるものなのでは?

というわけで「モナドをつくろう」の参考資料であるAndrzej FilinskiのRepresenting Monadsと、同じ著者によるMonadic Reflection in Haskellを読んでみた。

Representing Monadsの「5 Implementation and Examples」を見たところ:

(letfn [reflect [m]
  (shift [k] (bind m k))] ...)

(let [reify (macro [expr]
  (reset (return expr)))] ...)

という定義で特定のモナドbindreturn、そしてshiftresetがあればreifyreflectは書ける。

そして論文には出てないようだがreifyreflectがあればreturnbindは書ける:

(letfn [return [a] (reify a)] ...)

(let [bind (macro [m f] (reify (reflect (f (reflect m)))))] ...)

というわけでbindreturnreifyreflectの間にはかなり密接な関係がある。bindreturnreifyreflectだけで定義できるのに対し、reifyreflectbindreturnに加えてshiftresetが必要なことを考えるとreifyreflectのほうが強力なようだ。

reifyreflectとは、モナドAPIであるbindreturnと同程度以上の表現力(?)を持ち、専用のdo構文などを用意せずともdirect styleでモナディックなコードを書けるようにする関数(あるいはマクロ)ということになるだろうか。

というわけで、たしかにreifyreflectを実装しておけばとりあえず「モナドをつくった」と言えそうである。よかったよかった。