Scala 是不是;重置";要求;shift";在街区里面?

Scala 是不是;重置";要求;shift";在街区里面?,scala,continuations,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] scala>重置{} 错误:无法cps转换表达式():类型参数[单位,单位,无] 不符合

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] scala>重置{} 错误:无法cps转换表达式():类型参数[单位,单位,无] 不符合方法shiftUnit的类型参数界限[A,B,C>:B] 这看起来很合理(因为
reset
块中没有
shift
是“死代码”,它从未执行过),但我不理解错误


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

我不同意,
reset
中的代码在没有
shift
的情况下是死的。实际上,
reset
只是定义了一个延续的边界(这是因为它们被称为分隔的延续)。如果在
reset
中的某个地方有
shift
,而您不调用延续函数,那么代码就会失效。例如:

reset {
  println(1)
  shift((k: Unit => Unit) => println(2))
  println(3)
}
由于我没有调用
k(单位)
,所以
shift
之后的代码已失效(
println(3)

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

def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...
def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ...
shift
正好产生
reset
方法所期望的结果。以下是
shift
方法的定义:

def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...
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]