Je ne comprends pas les continuations de la frappe délimités de Scala (A @cpsParam [B, C])
-
19-09-2019 - |
Question
J'ai du mal à comprendre ce que signifie exactement quand une valeur est de type A @cpsParam[B,C]
et quels types de ce formulaire dois-je attribuer à mes valeurs lors de l'utilisation de l'installation de continuations délimitée.
Je l'ai regardé quelques sources:
http://lamp.epfl.ch/~rompf/continuations-icfp09 .pdf
http://www.scala-lang.org/node/2096
http://dcsobral.blogspot.com/2009 /07/delimited-continuations-explained-in.html
http://blog.richdougherty.com/2009 /02/delimited-continuations-in-scala_24.html
mais ils ne me donnent beaucoup d'intuition dans ce. Dans le dernier lien, l'auteur tente de donner une explication explicite, mais il ne suffit pas clair de toute façon.
A représente ici la sortie du calcul, qui est aussi l'entrée à son maintien. B représente le type de retour de ce prolongement, et le C représente son type de retour, car décalage « final » peut faire un traitement ultérieur à la valeur retournée et changer son type.
Je ne comprends pas la différence entre « sortie du calcul », « type de retour de la poursuite » et « type de retour final de la poursuite ». Ils sonnent comme des synonymes.
La solution
Alors, les gens m'a aidé avec celui-ci ailleurs. Voici la réponse:
reset ({
...
...shift((k:A=>B) => ...::C)::A...
...
}::B)::C
Alors, shift
est un trou de type A
dans un {...}
de calcul de type B
. L'argument de shift
retourne une valeur de type C
et c'est la raison pour laquelle reset ({...})
est de type C
.
L'astuce clé pour comprendre ce genre de choses était de voir que {...}
et reset {...}
ont différents types en fonction de ce que les rendements de type argument de la shift
.
Par exemple:
reset ({
"number "+shift((k:Int=>String) => List(k(1), k(2), k(3)))
})
renvoie List("number 1", "number 2", "number 3")
.
Ici A
est Int
, B
est String
, C
est List[String]
parce {"number" + _}
est (ici) une fonction de Int
à String
et l'argument de shift
, compte tenu de cette fonction, produit un List[String]
, qui devient la suite de la reset({...})
.
Autres conseils
Je suis encore en train de déterminer les règles / implications de frappe exacts impliqués ici.
Il semble facile / plus facile si les types dans les exemples sont indiqués ci-dessus, mais il devient plus interressant / difficile « assez simple » à « tenir bien » (au moins pour moi) en comparant les choses au typage donner par tiark Rompf:
|- e: A@cpsParam[B,C]; {[|r|]}: U
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )
donc le résultat de [|e|].map( (x: A) => {[|r|]} )
aura le type Shift[U,B,C]
selon la définition de la carte donnée dans le document de tiark.
Ici U est pas nécessairement la même chose que B.
Jusqu'à présent, je ne comprends pas pourquoi U est autorisé à être différent de B sans quelque chose comme
U <: B
donné dans la définition de la carte dans le document tiark.
Qu'est-ce que je suis absent ne repsectively comprendre ici?
Les conseils / idées?