开发者

Monad trait in Scala

(How) is it possible to represent mo开发者_开发百科nads in Scala in a generic way (like the Monad typeclass in Haskell)? Is it somehow possible to define a trait Monad for this purpose?


You could try something like this:

trait Monad[+M[_]] {
  def unit[A](a: A): M[A]
  def bind[A, B](m: M[A])(f: A => M[B]): M[B]
}

// probably only works in Scala 2.8
implicit def monadicSyntax[M[_], A](m: M[A])(implicit tc: Monad[M]) = new {
  private val bind = tc.bind(m) _

  def map[B](f: A => B) = bind(f compose tc.unit)

  def flatMap[B](f: A => M[B]) = bind(f)
}

implicit object MonadicOption extends Monad[Option] {
  def unit[A](a: A) = Some(a)

  def bind[A, B](opt: Option[A])(f: A => Option[B]) = opt flatMap f
}

You would of course define similar implicit objects for any other monad your heart desires. In Haskell terms, you can think of Monad like the typeclass and MonadicOption as a particular instance of that type class. The monadicSyntax implicit conversion simply demonstrates how this typeclass could be used to allow the use of Scala's for-comprehensions with anything which satisfies the Monad typeclass.

Generally speaking, most things in the Scala standard library which implement flatMap are monads. Scala doesn't define a generic Monad typeclass (though that would be very useful). Instead, it relies on a syntactic trick of the parser to allow the use of for-comprehensions with anything which implements the appropriate methods. Specifically, those methods are map, flatMap and filter (or foreach and filter for the imperative form).


You may find the scalaz project interesting; it has lots of other (functional) stuff as well besides an implementation of monads.


http://www.codecommit.com/blog/ruby/monads-are-not-metaphors

Here's a useful and rather lengthy article about the Monad pattern and its implementation in Scala by Daniel, who wrote the accepted answer for this question.

(For those who stumble upon this "ancient" question via the mystical ways of StackOverflow's site-search.)


Take a look at http://www.scala-lang.org/api/current/index.html#scala.collection.generic.FilterMonadic. A case class is already built into the language and used extensively throughout for collections...


Scala achieves similar power to Haskell's type classes through use of implicit parameters, particularly view bounds and context bounds. You can see such things in use particularly on Scala 2.8, with traits like Ordering and Numeric.

That said, look at the Scalaz project. It has monads, functors, arrows... the whole shebang.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜