Skip to content

Instantly share code, notes, and snippets.

@andimiller
Created October 22, 2021 21:34
Show Gist options
  • Save andimiller/993257026970f86ba5e753849604d7b7 to your computer and use it in GitHub Desktop.
Save andimiller/993257026970f86ba5e753849604d7b7 to your computer and use it in GitHub Desktop.
import cats.parse.Parser
import cats.implicits.*
import cats.*
import higherkindness.droste.*
object Calculator extends App:
// normal expression data structure
enum Expr:
case Add(a: Expr, b: Expr)
case Mul(a: Expr, b: Expr)
case Literal(i: Int)
// the recursive generic version
enum ExprF[F]:
case Add(a: F, b: F)
case Mul(a: F, b: F)
case Literal(i: Int)
given Functor[ExprF] with
def map[A, B](fa: ExprF[A])(f: A => B): ExprF[B] = fa match
case ExprF.Add(a, b) => ExprF.Add(f(a), f(b))
case ExprF.Mul(a, b) => ExprF.Mul(f(a), f(b))
case ExprF.Literal(i) => ExprF.Literal(i)
val interpret = Algebra[ExprF, Int] {
case ExprF.Add(a, b) => a+b
case ExprF.Mul(a, b) => a*b
case ExprF.Literal(i) => i
}
val project = Coalgebra[ExprF, Expr] {
case Expr.Add(a, b) => ExprF.Add(a, b)
case Expr.Mul(a, b) => ExprF.Mul(a, b)
case Expr.Literal(i) => ExprF.Literal(i)
}
import Expr.*
val run = scheme.hylo(interpret, project)
println(
run(
Add(Literal(100), Mul(Literal(2), Literal(2)))
)
) // 104
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment