Scalaの限定継続のshiftだけを含む関数オブジェクトを作れるかを実験
関数オブジェクトの定義の中にshiftを入れて、関数オブジェクトを別のメソッドに渡す、そのメソッドではresetの中でその関数オブジェクトを呼び出す、ってのができるかを実験した。
import scala.util.continuations.cpsParam; import scala.util.continuations.reset; import scala.util.continuations.shift; object test { def main(args: Array[String]){ val f: Int => Long @cpsParam[String, (String, String)] = { a: Int => shift { ctx: (Long => String) => val s = ctx(a * 10000L); (s, "test:f"); } } val g: Int => Long @cpsParam[String, (String, String)] = { a: Int => shift { ctx: (Long => String) => val s = ctx(a * 20000L); (s, "test:g"); } } sub(f); sub(g); } private def sub(f: Int => Long @cpsParam[String, (String, String)]){ val result: (String, String) = reset { val a: Int = 123; val b: Long = f(a); (a + b).toString; } println(result); } }
$ scalac -P:continuations:enable test.scala && scala test (1230123,test:f) (2460123,test:g)
作れるみたい。
REPLで限定継続を試すには、コンパイラのオプションと同様に
$ scala -P:continuations:enable
とする必要がある模様。
$ scala Welcome to Scala version 2.9.0.1 (OpenJDK 64-Bit Server VM, Java 1.6.0_20). Type in expressions to have them evaluated. Type :help for more information. scala> import scala.util.continuations._; import scala.util.continuations._ scala> val f = { a: Int => shift { ctx: (Long => String) => val s = ctx(a * 10000L); (s, "test:f"); } } <console>:10: error: this code must be compiled with the Scala continuations plugin enabled val f = { a: Int => shift { ctx: (Long => String) => val s = ctx(a * 10000L); (s, "test:f"); } } ^ scala> :quit $ scala -P:continuations:enable Welcome to Scala version 2.9.0.1 (OpenJDK 64-Bit Server VM, Java 1.6.0_20). Type in expressions to have them evaluated. Type :help for more information. scala> import scala.util.continuations._; import scala.util.continuations._ scala> val f = { a: Int => shift { ctx: (Long => String) => val s = ctx(a * 10000L); (s, "test:f"); } } f: (Int) => Long @scala.util.continuations.cpsParam[String,(String, java.lang.String)] = <function1> scala> f(3) None/None/Some((String,(String, java.lang.String))) <console>:12: error: found cps expression in non-cps position f(3) ^ scala> reset { f(3).toString; } res1: (String, java.lang.String) = (30000,test:f)