14 June, 2010

[Scala] Scala 2.8 Continuation (1)

root/compiler-plugins/continuations/trunk/doc/examples/continuationsに載っているサンプルコードをREPLで写経してみます。

Test0.scala

scala> import scala.util.continuations._
import scala.util.continuations._

scala> reset {
| 2 * {
| println("up")
| val x = shift((k:Int=>Int) => k(k(k(8))))
| println("down")
| x
| }
| }
up
down
down
down
res1: Int = 64

これはdef k(i:Int):Int = {println("down"); 2*i}と考えればOK。

Test1.scala

scala> object Test1 {
| def testThisMethod() = {
| 1 + (shift((k:Int=>Int) => k(k(k(17)))))
| }
| def testThisCallingMethod() = {
| testThisMethod() * 2
| }
| def m() {
| val result = reset(testThisCallingMethod())
| println(result)
| }
| }
defined module Test1

// ((((((17 + 1) * 2) + 1) * 2) + 1) * 2) = 150

scala> Test1.m()
150

k = (_+1)*2 と考えればこれも予想通りの結果。
resetの中にshiftを書くのはOKだが、resetなしでshiftだけの関数を定義しようとすると下記の様にエラーになります。仕方が無いのでobject Test1 {...} に包みます。

scala> def testThisMethod() = {
| 1 + (shift((k:Int=>Int) => k(k(k(17)))))
| }
:2: error: type mismatch;
found : Int @scala.util.continuations.cpsSynth @scala.util.continuations.cpsParam[Int,Int]
required: Int
object RequestResult$line4$object {
^


Test2.scala

scala> object Test2 {
| def methA() = {
| def fun(k:Int=>String) = {
| for(i <- List(1,2,3,4)) println(k(i))
| Some("returnvalue")
| }
| 2 * shift(fun)
| }
| def methB() = {
| "+++ "+methA().toString()
| }
| def m() = reset(methB())
| }
defined module Test2

scala> Test2.m()
+++ 2
+++ 4
+++ 6
+++ 8
res0: Some[java.lang.String] = Some(returnvalue)

k = "+++" + (2 * _).toString() ですか。

No comments: