2013-07-03 6 views
0

Я читаю сообщение о продолжении блога scala от here. К сожалению, это не работает на Скале 2.10.0:Scala продолжение типа ошибка

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

Вы уже поняли, что вам нужно изменить cps с cpsParam.

Если вы скомпилируете линию вне REPL внутри object, она действительно будет работать нормально. То, что вы видите, является артефактом того, что REPL делает за сценой, чтобы распечатать оценку того, что она читает. В РЕПЛ, когда вы набираете и увидеть что-то вроде:

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

По какой-то причине, что я не могу объяснить, код, который генерирует f:()Int строка присваивает результат f к фиктивной переменной, как это: lazy val $result = f. Вы можете увидеть это в действии, если вы запустите REPL с опцией -Xprint:parser. Это разоблачит многое из того, что происходит за сценой.

К сожалению, код, создающий фиктивное назначение, не понимает плагин продолжения, а синтезированный код недействителен.

Чтобы обойти эту проблему можно определить f внутри объекта в одном операторе, который будет обойти ленивое заявление 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, то РЕПЛ не пытается назначить результат - val, вот почему ваш второй пример работает.

+0

Это интересно. Спасибо за ответ. –

Смежные вопросы