Skip to content

Instantly share code, notes, and snippets.

@b-studios
Created June 8, 2016 13:19
Show Gist options
  • Save b-studios/bf59118640ca9edf62c4ba7cba8e1f56 to your computer and use it in GitHub Desktop.
Save b-studios/bf59118640ca9edf62c4ba7cba8e1f56 to your computer and use it in GitHub Desktop.
Some experiments with monadic object algebras
object monadicOA {
type ??? = Any
trait Monad[M[+_]] {
def unit[A]: A => M[A]
def bind[A, B]: M[A] => (A => M[B]) => M[B]
def map[A, B]: M[A] => (A => B) => M[B]
}
object Monad {
def unit[A, M[+_]](a: A)(implicit m: Monad[M]): M[A] = m.unit(a)
def bind[A, B, M[+_]](ma: M[A])(f: A => M[B])(implicit m: Monad[M]): M[B] = m.bind(ma)(f)
def map[A, B, M[+_]](ma: M[A])(f: A => B)(implicit m: Monad[M]): M[B] = m.map(ma)(f)
}
import Monad._
trait Expr[-Expr, +Out] {
def Lit: Int => Out
def Div: (Expr, Expr) => Out
// def Lambda: (Symbol, Expr) => Out
// def App: (Expr, Expr) => Out
// def Var: Symbol => Out
// def Lit: Int => Out
}
object Expr {
type Open[-Self, -E, Out] = Expr[E, (=> Self) => Out]
type Comonadic[-W[+_], -E, +Out] = Expr[W[E], Out]
trait Monadic[M[+_], -E, +Out] extends Expr[M[E], M[Out]] {
implicit def m: Monad[M]
}
}
type Value = Int
trait SimpleMEval[M[+_]] extends Expr.Monadic[M, Value, Value] {
def Lit = n => unit(n)
def Div = (l, r) =>
bind(l) { lv =>
bind(r){ rv => unit(lv / rv) }}
}
sealed trait Result[+A]
case class Success[+A](r: A) extends Result[A]
case object Failure extends Result[Nothing]
trait ExceptionEval extends SimpleMEval[Result] {
override def Div = (l, r) =>
bind(l) { lv =>
bind(r){
case 0 => Failure
case rv => unit(lv / rv)
}}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment