まず、話の前提として以下の記事とか読んでおいたほうがいいです。
モナドは合成できない( 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 にでてきますが、それ以外のことも色々書いてあるような。
誰かなにか知ってたら教えて下さい