Scala延续类型错误

Scala延续类型错误,scala,continuations,Scala,Continuations,我正在读《scala续集》的博客文章。不幸的是,这在scala 2.10.0上不起作用: def f():Int @cps[Int,Int] = {shift { (k:Int=>Int) => k(6) } - 1} <console>:10: error: wrong number of type arguments for util.continuations.cps, should be 1 def f():Int @cps[Int,Int] =

我正在读《scala续集》的博客文章。不幸的是,这在scala 2.10.0上不起作用:

def f():Int @cps[Int,Int] = {shift { (k:Int=>Int) => k(6) } - 1} 
<console>:10: error: wrong number of type arguments for util.continuations.cps, should be 1
       def f():Int @cps[Int,Int] = {shift { (k:Int=>Int) => k(6) } - 1} 
                ^
<console>:10: error: type mismatch;
 found   : Int @scala.util.continuations.cpsSynth 

@scala.util.continuations.cpsParam[Int,Int]
 required: Int
       def f():Int @cps[Int,Int] = {shift { (k:Int=>Int) => k(6) } - 1} 

您能解释一下为什么会发生这种情况吗?

您已经发现需要使用
cpsParam
更改
cps

如果在
对象
内的REPL外部编译该行,它实际上可以正常工作。您看到的是REPL在后台打印出其读取内容的评估结果的一个工件。在REPL中,当您键入并看到以下内容时:

scala> def f() = 1
f: ()Int
出于某种我无法解释的原因,生成
f:()Int
字符串的代码将
f
的结果分配给如下伪变量:
lazy val$result=f
。如果您使用
-Xprint:parser
选项启动REPL,您可以看到它的作用。它将揭露很多幕后发生的事情

不幸的是,创建虚拟赋值的代码不理解延续插件,合成的代码无效

要解决此问题,您可以在单个语句中的对象内部定义
f
,这将绕过lazy val语句:

$ scala -P:continuations:enable               
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_09).
Type in expressions to have them evaluated.
Type :help for more information.

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

scala> object F { def f():Int @cpsParam[Int,Int] = {shift { (k:Int=>Int) => k(6) } - 1} }
defined module F

scala> reset{ F.f() }
res0: Int = 5

当您向
f
添加一个伪参数时,REPL不会尝试将结果分配给
val
,这就是第二个示例工作的原因。

这很有趣。谢谢你的回复。
scala> def f() = 1
f: ()Int
$ scala -P:continuations:enable               
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_09).
Type in expressions to have them evaluated.
Type :help for more information.

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

scala> object F { def f():Int @cpsParam[Int,Int] = {shift { (k:Int=>Int) => k(6) } - 1} }
defined module F

scala> reset{ F.f() }
res0: Int = 5