No estoy de acuerdo, ese código dentro de reset
está muerto sin shift
. En realidad, reset
solo define los límites de una continuación (es porque se llaman delimitadas continuaciones). El código estaría muerto si tiene shift
en algún lugar dentro de reset
y no llama a la función de continuación. Por ejemplo:
reset {
println(1)
shift((k: Unit => Unit) => println(2))
println(3)
}
El código después shift
está muerto (println(3)
) porque no he llamado k(Unit)
.
De otro lado, parece que reset
espera algún tipo especial de retorno de ella de cuerpo - el que anota con @cpsParam
anotación. Puede comprobar definición de reset
método:
def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...
Y shift
produce justo lo reset
método espera. He aquí la definición de shift
método:
def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ...
Pero todavía se puede utilizar sin reset
shift
llamada dentro de ella. Este truco lo hará:
def foo[T](body: => T @cps[Any]) = reset(body)
foo {
println("it works")
}
Tenga en cuenta que se acaba de @cps
tipo de alias para @cpsParam
. Aquí está la definición:
type cps[A] = cpsParam[A, A]