以前この記事書いたときに
HaskellのdoとScalaのfor式とEitherとMonadPlus
MonadZeroというtypeclassに触れてなかったので、書こうと思います。
簡単にいうと、Monadを継承していて更にzeroというメソッドを一つだけもつものです。以下のようなHaskellの資料中にでてきます
http://www.haskell.org/haskellwiki/MonadPlus_reform_proposal
http://www.haskell.org/haskellwiki/Typeclassopedia ( 日本語訳もあるけどちょっと古い )
これなんかによると、1997年という自分が小学生くらいのころには、Monadにfailがなくて、かわりにMonadZeroがあったらしいです。*1
さて、まずこれをScalazで書いてみました。
https://github.com/xuwei-k/scalaz/compare/xuwei-k:768f656...xuwei-k:4dda3da
- leftZeroという、今までMonadPlusにあったlawをMonadZeroに移せる( haskellのこのページ に書いてあるもの)
- 同じく、filterもMonadPlusからMonadZeroに移せる
さて、そうするとEitherはMonadPlusにならかなったけど、MonadZeroにできます。がしかし、zero*2は Leftだったらなんでもlawを満たしてしてしまいます。*3
*4
なんだか気持ちわるいですね。
- ほかにLaw定義できないのか?
- そもそもMonadZero有用なのか?*5
- MonadZeroのzeroが一意に定まらない場合どうするべきか?
- MonadPlusにならないけど、MonadZeroになるわかりやすい例ほかにないかな?
などなど、色々疑問が残りますが、それらを書く知識が全く無いので、ひとまずこれで終わりにします
*1:余談ですが、 highj に MonadZero がありますね https://code.google.com/p/highj/source/browse/branches/java8/src/main/java/org/highj/typeclass/monad/MonadZero.java?r=132
*2:scalazで実装した場合、既存の名前に合わせるためにemptyという名前にした
*3:たとえば、 MonadZero[({type λ[α]= Either[Int,α]})] なら、Left(0)を返してもLeft(1)を返しても満たすということ
*4:もちろん、毎回違う値返したら失敗しますし、なんからの固定値を返す必要はありますが
*5:それがよくわからないので、もちろんさっきのコードはpull reqしません