Skip to content

Instantly share code, notes, and snippets.

@halcat0x15a
Created January 2, 2013 08:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halcat0x15a/4433117 to your computer and use it in GitHub Desktop.
Save halcat0x15a/4433117 to your computer and use it in GitHub Desktop.
package mymonad
import scala.language.postfixOps
import scala.util.continuations._
import scala.util.control.NonFatal
sealed trait MyOption[+A]
case object MyNone extends MyOption[Nothing]
case class MySome[+A](value: A) extends MyOption[A]
object MyOption {
def option[B](f: Monad[B] => MyOption[B] @ cps[MyOption[B]]) = reset(f(new Monad[B]))
implicit class BindOps[A: Monad](a: MyOption[A]) {
def bind = implicitly[Monad[A]] bind a
}
implicit class PureOps[A: Monad](a: A) {
def pure = implicitly[Monad[A]] pure a
}
private class Monad[B] {
def bind[A](m: MyOption[A]) = shift((k: A => MyOption[B]) =>
m match {
case MyNone => MyNone
case MySome(a) => k(a)
}
)
def pure(x: B) = MySome(x)
}
}
object Main extends App {
def toInt(s: String) =
try MySome(s.toInt) catch { case NonFatal(_) => MyNone }
import MyOption._
val x = option[Int] { implicit m =>
val a = toInt("1") bind
val b = toInt("2") bind
val c = toInt("3") bind;
a + b + c pure
}
assert(x == MySome(6))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment