Last active
February 7, 2019 13:25
-
-
Save sergey-scherbina/ef5ae13d29363a39e321968d1456f113 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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