Skip to content

Instantly share code, notes, and snippets.

@b-studios
Last active February 3, 2017 15:23
Show Gist options
  • Save b-studios/1857821cfeddc4fdf98198ad3eba9cb3 to your computer and use it in GitHub Desktop.
Save b-studios/1857821cfeddc4fdf98198ad3eba9cb3 to your computer and use it in GitHub Desktop.
Effect handlers as solution to the expression problem
effect expr<a> {
lit (n: int): a;
add (l: a, r: a): a
}
effect mulExpr<a> {
mul (l: a, r: a): a
}
// forall<a,e>. (() -> <expr<int>|e> a) -> e a
val eval = handler {
lit (n) -> resume(n)
add (l, r) -> resume(l + r)
}
// also count reduction steps
val eval2 = handler(s) {
return x -> (s, x)
lit (n) -> resume(s + 1, n)
add (l, r) -> resume(s + 1, l + r)
}
val pretty = handler {
lit (n) -> resume(n.show)
add (l, r) -> resume(l + "+" + r)
}
fun tuple(alg1, alg2) {
handler {
lit (n) -> resume((alg1({ lit(n) }), alg2({ lit(n) })))
add (l, r) -> resume((alg1({ add(l.fst, r.fst) }), alg2({ add(l.snd, r.snd) })))
}
}
val counter = handler(c=0) {
return x -> (c, x)
lit (n) -> resume(c + 1, lit(n))
add (l, r) -> resume(c + 1, add(l, r))
}
// forall<a,e>. (() -> <mulExpr<int>|e> a) -> e a
val mulEval = handler {
mul (l: int, r: int) -> resume(l * r)
}
fun t1() {
add(lit(1), lit(2))
}
// forall<a>. <expr<a>, mulExpr<a>> a
fun term() {
add(lit(1), mul(lit(2), lit(3)))
}
// forall<a>. <expr<a>,mulExpr<a>> a
fun both() {
add(t1(), term())
}
fun handleBoth(e) {
eval({mulEval(e)})
}
fun main() {
println( tuple(eval, pretty)( t1 ).fst );
println( tuple(eval, pretty)( t1 ).snd )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment