Pergunta

Estou lutando para entender o que significa precisamente quando um valor tem tipo A @cpsParam[B,C] e que tipos deste formulário devo atribuir aos meus valores ao usar o recurso de continuação delimitado.

Eu olhei para algumas fontes:

http://lamp.epfl.ch/~trompf/continuations-icfp09.pdf

http://www.scala-lang.org/node/2096

http://dcsobral.blogspot.com/2009/07/delimited-continuations-explined-in.html

http://blog.richdougherty.com/2009/02/delimited-continuations-in-scala_24.html

Mas eles não me deram muita intuição a isso. No último link, o autor tenta dar uma explicação explícita, mas não é claro o suficiente de qualquer maneira.

O A aqui representa a saída do cálculo, que também é a entrada para sua continuação. O B representa o tipo de retorno dessa continuação, e o C representa seu tipo de retorno "final" - porque a mudança pode fazer um processamento adicional para o valor retornado e alterar seu tipo.

Não entendo a diferença entre "saída do cálculo", "tipo de retorno da continuação" e "Tipo de retorno final da continuação". Eles parecem sinônimos.

Foi útil?

Solução

Então, as pessoas me ajudaram com isso em outro lugar. Aqui está a resposta:

reset ({
    ...
    ...shift((k:A=>B) => ...::C)::A...
    ...
}::B)::C

Então, shift é um buraco do tipo A em um cálculo {...} do tipo B. O argumento de shift Retorna um valor do tipo C e é por isso reset ({...}) tem tipo C.

O truque principal para entender esse material era ver que {...} e reset {...} tem tipo diferente, dependendo de que tipo de shiftO argumento de Returna.

Por exemplo:

reset ({
    "number "+shift((k:Int=>String) => List(k(1), k(2), k(3)))
})

retorna List("number 1", "number 2", "number 3").

Aqui A é Int, B é String, C é List[String] Porque {"number" + _} é (aqui) uma função de Int para String e o argumento de shift, dada essa função, produz um List[String], que se torna resultado do reset({...}).

Outras dicas

Ainda estou em um processo de descobrir as regras/implicações exatas de digitação envolvidas aqui.

Parece fácil/mais fácil se os tipos nos exemplos forem "simples o suficiente" para "se encaixar bem", como mostrado acima, mas se torna mais interrevagante/difícil (pelo menos para mim) ao comparar as coisas com a digitação do TIARK ROMPF:

|- e: A@cpsParam[B,C]; {[|r|]}: U
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )

Então, o resultado de [|e|].map( (x: A) => {[|r|]} ) terá o tipo Shift[U,B,C] De acordo com a definição de mapa dado no artigo de Tiark.

Aqui você não é necessariamente o mesmo que B.

Até agora eu não entendo por que você pode ser diferente de B sem algo comoU <: B dado na definição de mapa no artigo de Tiark.

O que estou perdendo o Repsectivamente, deixando de entender aqui?

Alguma dica/idéias?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top