11

reset要求shift在块内是否正确?我试了一下,得到了以下结果:

斯卡拉>重置{}
错误:无法 cps 转换表达式 ():类型参数 [Unit,Unit,Nothing]
不符合方法 shiftUnit 的类型参数界限 [A,B,C >: B]

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

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

4

1 回答 1

4

我不同意,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]
于 2011-05-27T17:18:29.827 回答