2013-07-03 101 views
0

我正在阅读从here斯卡拉延续博客文章。不幸的是,这并不在斯卡拉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} 

同样的问题,如果我尝试了建议的类型:

def f():Int @cpsParam[Int,Int] = {shift { (k:Int=>Int) => k(6) } - 1} 
<console>:4: error: type mismatch; 
found : Int @scala.util.continuations.cpsSynth 
@scala.util.continuations.cpsParam[Int,Int] 
required: Int 
object $eval { 

如果我添加一个未使用的输入参数,它不会抱怨:

def f2(x:Int):Int @cpsParam[Int, Int=>Int] = shift { (k:Int=>Int) => k } -1 
f2: (x: Int)Int @scala.util.continuations.cpsParam[Int,Int => Int] 

reset(f2(1))(0) 
res12: Int = -1 

你能解释为什么会发生这种情况吗?

回答

1

您已经知道您需要更改cpscpsParam

如果您在object内编译REPL以外的行,它实际上可以正常工作。你所看到的是REPL在场景后面进行的工作,以便打印出评估结果。在REPL当你输入和看到:

scala> def f() = 1 
f:()Int 

出于某种原因,我无法解释,产生了f:()Intf结果分配给这样一个虚拟变量的代码:lazy val $result = f。如果使用-Xprint:parser选项启动REPL,可以看到它在运行。它将揭露幕后发生的很多事情。

不幸的是,创建虚拟分配的代码不理解延续插件,并且合成的代码无效。

要解决这一点,你可以定义f在一个语句的对象,这将规避懒VAL语句中:当您添加一个虚拟参数f

$ 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 

,在REPL不尝试分配结果为val,所以这就是为什么你的第二个例子工作。

+0

这很有趣。感谢您的回复。 –