Skip to content

Instantly share code, notes, and snippets.

@sergey-scherbina
Last active February 7, 2019 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergey-scherbina/ef5ae13d29363a39e321968d1456f113 to your computer and use it in GitHub Desktop.
Save sergey-scherbina/ef5ae13d29363a39e321968d1456f113 to your computer and use it in GitHub Desktop.
package sandbox
import scala.annotation.tailrec
import scala.util.continuations.{cps, _}
/*
Introduction to Programming with Shift and Reset
http://pllab.is.ocha.ac.jp/~asai/cw2011tutorial/main-e.pdf
*/
object TestScalaCont extends App {
val x: Int = reset(3 + shift((k: Int => Int) =>
if (k(20) < 20) 20 else k(30)) - 1) + 1
// 3 + [.] - 1 <=> (x => 3 + x - 1)
println(x)
val y: String = reset(3 + shift((_: Int => Int) => "Hello") - 1) + 1
println(y)
val xx = reset(3 + ?[Int] - 1)
println(xx(2))
println(xx(20))
def ?[T] = shift(identity[T => T])
def f1 = 3 + ?[Int] * 2
val f = reset(f1 - 1)
println(f(10))
println(f(20))
sealed trait Tree // {
case class Node(l: Tree, n: Int, r: Tree) extends Tree
case object Empty extends Tree
//}
sealed trait Result[+T]
case class Next[T](n: T, k: Unit => Result[T]) extends Result[T]
case object Done extends Result[Nothing]
def Return[T](t: T)(k: Unit => Result[T]): Result[T] = Next[T](t, k)
@inline def Yield[T](t: T): Unit@cps[Result[T]] = shift(Return[T](t))
def start[T, R](t: T)(f: T => Unit@cps[Result[R]]): Result[R] = reset {
f(t);
Done: Result[R]
}
def startTree(t: Tree): Result[Int] = start(t)(walk)
def walk(t: Tree): Unit@cps[Result[Int]] = t match {
case Empty => ()
case Node(l, n, r) => {
walk(l)
Yield(n)
walk(r)
}
}
@tailrec def consume[T, R](t: T, f: T => R)(res: Result[T]): T = res match {
case Done => t
case Next(n, k) =>
f(n)
consume(t, f)(k())
}
//def consumeTree[T](tr: Tree)(t: T)(f: Int => T): T = consume(t, f)(start(tr))
def printNodes(t: Tree, stop: Int) = {
//consumeTree(t)(println)
def loop(r: Result[Int]): Unit = r match {
case Done => ()
case Next(n, k) =>
println(n)
if (n != stop)
loop(k())
}
loop(startTree(t))
}
def addTree(t: Tree): Int = {
def loop(r: Result[Int]): Int = r match {
case Done => 0
case Next(n, k) => n + loop(k())
}
loop(startTree(t))
}
val tr = Node(Node(Empty, 1, Empty), 2, Node(Empty, 3, Empty))
println("printNodes")
printNodes(tr, 2)
println("addtree")
println(addTree(tr))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment