MonadZero

以前この記事書いたときに

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しません