2013-07-03 147 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

這很有趣。感謝您的回覆。 –