Skip to content

Instantly share code, notes, and snippets.

@soc
Last active August 29, 2015 13:57
Show Gist options
  • Select an option

  • Save soc/9617078 to your computer and use it in GitHub Desktop.

Select an option

Save soc/9617078 to your computer and use it in GitHub Desktop.
package continuations
import avian.Continuations.reset
import avian.Continuations.shift
import java.util.concurrent.Callable
import avian.{ Function => AvianFunction }
import avian.FunctionReceiver
object ScalaContinuations extends App {
implicit def functionToAvianFunction[T](func: (T => T)): AvianFunction[T] =
new AvianFunction[T] { def call(argument: T): T = func(argument) }
implicit def functionToFunctionReceiver[T](func: (T => T) => T): FunctionReceiver[T] =
new FunctionReceiver[T] {
def receive(continuation: AvianFunction[T]): T = func(continuation.call)
}
implicit def functionToCallable[T](func: => T): Callable[T] =
new Callable[T] { def call(): T = func }
val result1 =
reset(new Callable[Int] {
def call() = 1 + shift(
new FunctionReceiver[Int] {
def receive(continuation: AvianFunction[Int]) = continuation.call(5)
})
})
val result2 =
reset(new Callable[Int] {
def call() = 1 + shift((continuation: Int => Int) => continuation(5))
})
val result3 =
reset(1 + shift((continuation: Int => Int) => continuation(5)))
val result4 =
reset(
1 + shift((continuation: Int => Int) => continuation(5))
+ shift((continuation: Int => Int) => continuation(5)))
val result5 = reset {
shift { (k: Int => Int) =>
k(k(k(7)))
} + 1
} * 2 // result 20
def a(x: Int) = shift { k: (Int => Int) => k(x) }
// Wrong algorithm, but who cares?
def fib(n: Int): Int = n match {
case x if (x > 2) => fib(x - 2) + fib(x - 1)
case x => a(x)
}
val result6 = reset { fib(5) }
val result7 = reset { fib(12) }
def fib2(n: Int): Int = {
def fib0(n: Int, sub1: Int, sub2: Int): Int = n match {
case x if (math.abs(x) < 2) => shift { k: (Int => Int) => k(x) }
case x => fib0(x - sub1, sub1, sub2) + fib0(x - sub2, sub1, sub2)
}
val s = math.signum(n)
fib0(n - s, s, s * 2)
}
val result8 = reset { fib2(0) }
println(result1 ensuring (_ == 6))
println(result2 ensuring (_ == 6))
println(result3 ensuring (_ == 6))
println(result4 ensuring (_ == 11))
println(result5 ensuring (_ == 20))
println(result6)
println(result7)
println(result8)
val fibonacciNumbers = List(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169)
(0 to 20) foreach (n => println(reset { fib2(n+1) }.ensuring(_ == fibonacciNumbers(n), (n, reset { fib2(n+1) }, fibonacciNumbers(n)))))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment