bonotakeの日記

元・ソフトウェア工学系研究者、今・AI系エンジニア

コモニャドセミナーに行ってきた

参照:

以下メモ。

スタンピング・モナド

Haskellで一番スタンピング・モナドっぽいのは、Writerモナドかなーと思いました*1。というのは、

計算のタイプ: 計算された値にとは別にデータのストリームを生成する計算

とかありますが、生成ストリームのところがモノイドで定義されるので。

newtype Writer w a = Writer {runWriter :: (a, w)}

instance (Monoid w) => Monad (Writer w) where
    return a = Writer (a, mempty)
    m >>= k  = Writer $ let
        (a, w)  = runWriter m
        (b, w') = runWriter (k a)
        in (b, w `mappend` w')

ここで、memptyはモノイドの単位、mappendはモノイドの乗算(名前は加算だけど)。タプルを作って、第一要素は普通の計算結果を、第二要素はモノイドの乗算の結果を返しています。

昔、しりとりモナドってのをこのWriterモナドで書いてみました。あんまりうまく書けた気がしてないのですが、一応参照しときます。

モナドに0をぶちこむ

などという質問をしてみたのは、やっぱりHaskellモナドを考えていたからで。Haskellモナドって、いわゆる数学のモナド的な演算のほかに"fail"って関数を用意してて、要は例外によるエスケープ機構が別途くっついてるんですよね。
もしかしたら、0ぶち込んだらfailしてくれたりしないかなー、あれもしかして、Haskellモナドってただのモナドじゃなくて、0に対する演算を足したりしてる?? とかイイカゲンな妄想をしていたんですが。


そしたらまぁ、たまたま(本当にたまたま)例外モナドHaskellでいうMaybeモナド)の話になって、妄想はやはり妄想だったことが確認されつつ妙に納得されたのでありました。めでたしめでたし。

ちなみに、後から見ると

fail 関数は、モナドの数学的定義においても要請されている 部分ではありません。

だそうですwww
…がまぁ、Haksellのモナドは明示的に定義されるモナド以外に、例外モナドが裏で標準装備されてるんだ*2とも考えられなくもない、ってまたいい加減なこと書いてるかもしれませんが。

ちなみに、Maybeモナドはこの裏表が完全に一致します。

総括

モナドの話がやっぱりきけなかったー!

というか、コモナドのセミナーというより「小モニャドセミナー」だった気が。ちゃんちゃん。


いつもは懇親会に出ずに帰っちゃうので、今回は参加者の皆さんと話せて楽しかったです。

*1:というか、Haskellのタプルを直積とみなせば、定義的には直積スタンピング・モナドそのものではないかと思います。

*2:といっても、failのインスタンス定義は明示的に与えないといけませんが。

注:bonotakeは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。