2011-05-15 10 views
11

¿Es correcto que reset requiera shift dentro del bloque? Lo probé y tengo la siguiente:¿"reiniciar" requiere "cambio" dentro del bloque?

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]

Parece razonable (desde reset bloque sin shift interior es "código muerto", que nunca se ejecuta), pero no entiendo el error.

¿Cuál es el significado exacto del mensaje de error?

Respuesta

4

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 resetshift 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] 
Cuestiones relacionadas