Maybe とか Option とか

Option をあれこれ

Scala の Option は Haskell における Maybe と大体同じである。

なので

class Maybe[T](opt: Option[T])
{
  def >>=[U](f:(T=>Option[U])) = opt flatMap f
}

implicit def optionToMaybe[T](opt: Option[T]) = new Maybe(opt)

という定義をしてあげれば

def test(t:Int): Option[Int] = Some(10*t)

val x = Some(10)

println(x >>= test >>= test >>= test) // Some(10000)

って書けるよね。みたいな。


これと同じように

class MaybeFunc[A,B](f: (A=>Option[B]))
{
  def =<< (opt: Option[A]) = opt flatMap f
}

implicit def funcToMaybeFunc[A,B](f: (A=>Option[B])) = new MaybeFunc(f)

という定義をしてあげれば

println(test =<< x)

と書けるかと思いきや書けない。

println(test _ =<< x)

として placeholder を追加してあげないといけないのね。
そもそも結合方向違うから連続して書けないしね。

やっていることは

println(x flatMap test flatMap test flatMap test)

と同じだからそんなに意味はないかも。

Collection もあれこれ

Collection に対しても

// Monad 則満たさないけど
class ListMonad[T](c: Traversable[T])
{
  def >>=[V](f: (T=>Traversable[V])) = c flatMap f
}

implicit def traversableToListMonad[T](m: Traversable[T]) = new ListMonad(m)

という定義を追加してあげれば

def mul(f:Int) = List(f, f, f)

val x = List(1)

println(x >>= mul >>= mul) // List(1, 1, 1, 1, 1, 1, 1, 1, 1)

と書けるよね。

Option と Collection は同じ flatMap を呼んでいるだけなのに定義が別々になるのはちょっとスッキリしないんだけど、これを何とかすることはできるのだろうか。