reset
要求shift
在块内是否正确?我试了一下,得到了以下结果:
斯卡拉>重置{} 错误:无法 cps 转换表达式 ():类型参数 [Unit,Unit,Nothing] 不符合方法 shiftUnit 的类型参数界限 [A,B,C >: B]
它看起来很合理(因为reset
没有shift
内部的块是“死代码”,它永远不会执行)但我不明白这个错误。
错误消息的确切含义是什么?
reset
要求shift
在块内是否正确?我试了一下,得到了以下结果:
斯卡拉>重置{} 错误:无法 cps 转换表达式 ():类型参数 [Unit,Unit,Nothing] 不符合方法 shiftUnit 的类型参数界限 [A,B,C >: B]
它看起来很合理(因为reset
没有shift
内部的块是“死代码”,它永远不会执行)但我不明白这个错误。
错误消息的确切含义是什么?
我不同意,reset
没有shift
. 实际上reset
只是定义了延续的边界(那是因为它们被称为定界shift
延续)。如果你有某个地方reset
并且你不调用延续函数,那么代码就会死掉。例如:
reset {
println(1)
shift((k: Unit => Unit) => println(2))
println(3)
}
之后的代码shift
是 dead( 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]