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
是“死代码”,它永远不会被执行)但我不明白错误。
错误消息的确切含义是什么?
答案 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}}