Skip to content

Instantly share code, notes, and snippets.

@razie
Created July 26, 2011 16:10
Show Gist options
  • Save razie/1107128 to your computer and use it in GitHub Desktop.
Save razie/1107128 to your computer and use it in GitHub Desktop.
OO friendly monad
//Tony's monad
trait Monad[F[_]] {
def point[A](a: => A): F[A]
def bind[A, B](f: A => F[B]): F[A] => F[B]
}
//a Scala and OO-friendly monad
trait ScalaMonad[A] {
def flatMap[B](f: A => ScalaMonad[B]): ScalaMonad[B] // checkout the return value compared to the bind()
def map[B](f: A => B): ScalaMonad[B]
}
class ScalaMonadAdapter[A, F[_], M <: Monad[F]](val container: F[A], val m: M) extends ScalaMonad[A] {
def flatMap[B](f: A => ScalaMonad[B]): ScalaMonad[B] =
new ScalaMonadAdapter[B, F, M](
m.bind({ a: A => f(a).asInstanceOf[ScalaMonadAdapter[B, F, M]].container })(container), m)
def map[B](f: A => B): ScalaMonad[B] =
new ScalaMonadAdapter[B, F, M](
m.bind({ a: A => f(a).asInstanceOf[ScalaMonadAdapter[B, F, M]].container })(container), m)
}
object Main {
def test1(m: ScalaMonad[Int]) =
for (i <- m) yield i
def test2(s: ScalaMonad[ScalaMonad[Int]]) =
for (m <- s; i <- m) yield i
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment