“重置”是否需要在块内“移位”?

时间:2011-05-15 08:58:38

标签: scala continuations

reset在块内需要shift这是否正确?我试了一下,得到了以下内容:

scala> reset {} 
error: cannot cps-transform expression (): type arguments [Unit,Unit,Nothing]
do not conform to method shiftUnit's type parameter bounds [A,B,C >: B]

看起来合理(因为reset块内部没有shift是“死代码”,它永远不会被执行)但我不明白错误。

错误消息的确切含义是什么?

1 个答案:

答案 0 :(得分:4)

我不同意,reset内的代码在没有shift的情况下已经死亡。实际上reset只是定义了延续的边界(因为它们被称为分隔延续)。如果shift位于reset的某个地方,代码将会死亡而你不称之为延续功能。例如:

reset {
  println(1)
  shift((k: Unit => Unit) => println(2))
  println(3)
}

shift之后的代码已死(println(3)),因为我没有调用k(Unit)

另一方面,似乎reset期望从它的主体获得一些特殊的返回类型 - 用@cpsParam注释注释的类型。您可以查看reset方法的定义:

def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...

shift生成reset方法所期望的内容。以下是shift方法的定义:

def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ...

但您仍然可以在reset内使用shift来使用def foo[T](body: => T @cps[Any]) = reset(body) foo { println("it works") } 。这个技巧会做到这一点:

@cps

请注意,@cpsParam只是type cps[A] = cpsParam[A, A] 的类型别名。这是它的定义:

{{1}}