Skip to content

Instantly share code, notes, and snippets.

@andyscott
Last active December 6, 2016 05:34
Show Gist options
  • Select an option

  • Save andyscott/6be406aeac9ea16d6f1f0032bcfc1026 to your computer and use it in GitHub Desktop.

Select an option

Save andyscott/6be406aeac9ea16d6f1f0032bcfc1026 to your computer and use it in GitHub Desktop.
import cats._
import cats.syntax.all._
object FooAlgebra {
sealed trait Op[A]
case object Foo extends Op[String]
case class FooOps[F[_]](lift: Op ~> F = interpreter) {
def foo(): F[String] = lift(Foo)
}
val interpreter: Op ~> Id = λ[Op ~> Id] {
case Foo ⇒ "Foo"
}
}
object BarAlgebra {
sealed trait Op[A]
case object Bar extends Op[String]
case class BarOps[F[_]](lift: Op ~> F = interpreter) {
def bar(): F[String] = lift(Bar)
}
val interpreter: Op ~> Id = λ[Op ~> Id] {
case Bar ⇒ "Bar"
}
}
object BazAlgebra {
sealed trait Op[A]
case object Baz extends Op[String]
case class BazOps[F[_]](lift: Op ~> F) {
def baz(): F[String] = lift(Baz)
}
class BazInterpreter[F[_]: Monad](
fooOps: FooAlgebra.FooOps[F],
barOps: BarAlgebra.BarOps[F]
) extends (Op ~> F) {
override def apply[A](op: Op[A]): F[A] = op match {
case Baz ⇒ for {
foo ← fooOps.foo()
bar ← barOps.bar()
} yield s"$foo$bar"
}
}
}
object TracerApp {
def main(args: Array[String]): Unit = {
val fooOps0 = FooAlgebra.FooOps()
val barOps0 = BarAlgebra.BarOps()
val bazOps0 = BazAlgebra.BazOps(
new BazAlgebra.BazInterpreter(fooOps0, barOps0))
val res0 = bazOps0.baz()
println(s"baz0: $res0")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment