简体   繁体   English

Scala延续类型错误

[英]Scala continuation type error

I am reading the scala continuation blog post from here . 我正在从这里阅读scala延续博客文章。 Unfortunately this does not work on scala 2.10.0: 不幸的是,这在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} 

Same deal if I tried the suggested type: 如果我尝试建议的类型,则同样的事情:

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 {

If I add an unused input parameter, it does not complain: 如果添加未使用的输入参数,则不会出现错误:

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

Can you explain why this is happening? 您能解释为什么会这样吗?

You already figured out you need to change cps with cpsParam . 您已经确定需要使用cpsParam更改cps

If you compile the line outside of the REPL inside an object , it will actually work fine. 如果在object内部的REPL外部编译该行,则实际上可以正常工作。 What you see is an artifact of what the REPL does behind the scene to print out the evaluation of what it reads. 您所看到的是REPL在后台进行操作以打印出所读取内容的评估的结果。 In the REPL when you type and see something like: 在REPL中,当您键入并看到如下内容:

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

For some reason that I cannot explain, the code that generates the f: ()Int string assigns the result of f to a dummy variable like this: lazy val $result = f . 出于某种我无法解释的原因,生成f: ()Int字符串的代码会将f的结果分配给如下所示的虚拟变量: lazy val $result = f You can see it in action if you start the REPL with the -Xprint:parser option. 如果使用-Xprint:parser选项启动REPL,则可以看到它的作用。 It will expose a lot of what happens behind the scene. 它将揭示很多幕后发生的事情。

Unfortunately that code that creates the dummy assignment does not understand the continuation plug-in and the synthetized code is not valid. 不幸的是,创建虚拟分配的代码无法理解延续插件,并且合成的代码无效。

To work around this you can define f inside an object in a single statement which will circumvent the lazy val statement: 要解决此问题,您可以在单个语句中定义对象内部的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

When you add a dummy parameter to f , the REPL does not try to assign the result to a val , so that's why your second example works. 当您将伪参数添加到f ,REPL不会尝试将结果分配给val ,因此这就是第二个示例起作用的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM