Does "reset" require "shift" inside the block?
Is it correct that reset
requires shift
inside the block? I tried it and got the following:
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]
It looks reasonable (since reset
block without开发者_StackOverflow社区 shift
inside is "dead code", which is never executed) but I do not understand the error.
What is the exact meaning of the error message?
I don't agree, that code within reset
is dead without shift
. Actually reset
just defines the boundaries of a continuation (that's because they are called delimited continuations).The code would be dead if you have shift
somewhere within reset
and you do not call continuation function. For example:
reset {
println(1)
shift((k: Unit => Unit) => println(2))
println(3)
}
The code after shift
is dead (println(3)
) because I have not called k(Unit)
.
From the other hand, seems that reset
expects some special return type from it's body - the one that annotated with @cpsParam
annotation. You can check definition of reset
method:
def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...
And shift
produces just what reset
method expects. Here is definition of shift
method:
def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ...
But you still can use reset
without shift
call within it. This trick will do it:
def foo[T](body: => T @cps[Any]) = reset(body)
foo {
println("it works")
}
Please note, that @cps
is just type alias for @cpsParam
. Here it's definition:
type cps[A] = cpsParam[A, A]
精彩评论