Scalazでモナドの合成

まず、話の前提として以下の記事とか読んでおいたほうがいいです。

モナドは合成できない( Translated Tony Morris's "Monads do not compose")
合成できるモナド、モナドが合成できる時


それで、

everpeaceさんが書いている
M[ N[_] ]からN[ M[_] ]へswapできるという性質
をtypeclassで表して、Scalazに組み込んでみよう!

と思いたち、やってみて、それっぽくできたのがこち

https://github.com/xuwei-k/scalaz/compare/scalaz:b8ad416...xuwei-k:6a5e4a6



(余談ですが、これやってる途中にバグ見つけました)
https://github.com/scalaz/scalaz/pull/364



そして、その後
「あれ、M[ N[_] ]からN[ M[_] ]へswapって、Traverseのsequence関数では?」
と気付き
Monadを合成する場合、Traverseのtypeclassのインスタンスであることを要求する」
という方法でやってみたのがこち


https://github.com/xuwei-k/scalaz/compare/scalaz:b8ad416...xuwei-k:12fee3e



  • どちらも、とりあえずpull reqするつもりはありません
  • ほとんど興味本位でやってみただけで、実際、これらがScalazに存在して便利なのかどうなのかよくわからない
  • OptionTとかListTとかEitherTとかを直接書いたほうが、実用上便利?
  • Swapableのほうは、名前もダサいし、わざわざtypeclassを2つも作るのもなんだかカッコ悪い気がする
  • Traverseのsequenceを使っての実装が、理論的に必ず正しいのか、全くわからないし自信がない
  • Traverseではなく、もっと制限緩くできる?


ところで、これと関係あるような微妙な話ですが、tixxitさんがtraversable-monadtransというbranchで
「MonadTransformerのコードを共通化する仕組み」
を作ってるみたいです。そのうちpull reqするのかな

https://github.com/tixxit/scalaz/compare/scalaz:b8ad416...tixxit:2815140



このあたりの話になると、Haskellが関連するような論文調べればいっぱいでてきますが、ちょっと読んだくらいではよくわからないですね・・・。たとえば、「swapできれば合成できる」というような話は、この論文 http://web.cecs.pdx.edu/~mpj/pubs/composing.html にでてきますが、それ以外のことも色々書いてあるような。
誰かなにか知ってたら教えて下さい