2010-11-16 5 views
2

Je suis encore en train de déterminer les règles de typage exactes/implications impliquées ici.scala continuations dactylographiées

Il semble facile/facile si les types dans les exemples sont "assez simples" pour "bien s'adapter" comme dans presque tous les exemples simples est le cas, mais il devient plus interressant/difficile (au moins pour moi) en comparant les choses à la frappe donnée par tiark Rompf:

|- e: [email protected][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 le même 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ée dans la définition de la carte dans le document de tiark.

Qu'est-ce que je manque respectivement de ne pas comprendre ici?

Des astuces/idées?

Répondre

1

J'ai eu un deuxième regard à ce sujet car je voulais voir ce que le résultat de la transformation cps sélective donnera dans les deux cas.

  1. U <: B
  2. U n'est pas un sous-type B

je l'exemple simple suivant:

package sample 

import scala.util.continuations._ 

class Depp { 
    override def toString = "DEPP" 
} 

class Sepp extends Depp { 
    override def toString = "DEPP->SEPP" 
} 

object Sample extends Application { 
    val depp = new Depp 
    val sepp = new Sepp 
    val res = reset { 
    shift { 
     (k: Int => Depp) => k(7) 
    } 
    val z = sepp 
    z 
    } 
    println("Result = "+ res) 
} 

utilisant ce Compiler

scalac -P : continuations: enable -Xprint: selectivecps Sample.scala

est un succès et donne les éléments suivants (partie intéressante uniquement):

private[this] val res: sample.Depp = scala.util.continuations.package.reset[sample.Sepp, sample.Depp]({ 
    package.this.shiftR[Int, sample.Depp, sample.Depp](((k: (Int) => sample.Depp) => k.apply(7))).map[sample.Sepp] 
    tmp1; 
    val z: sample.Sepp = Sample.this.sepp; 
    z 
    })) 

ok donc le type de résultat (application de la carte) objet Shift est [Sepp,Depp,Depp] comme prévu :)

ce qui est bien parce que Je comprends comment les objets Shift comme [email protected][A,C] sont apparus (la fonction de réinitialisation donnée dans le papier de Tiark fonctionne sur de tels objets Shift)

Maintenant, en changeant ce qui suit dans l'exemple simple pour donner un type sans rapport avec Depp: z.asInstanceOf[Float]

compilation avec cette

scalac -P: continuations: permettre -Xprint: selectivecps de Sample.scala

apporte l'erreur suivante qui indique ce qui est réellement vérifié:

Sample.scala:16: error: type mismatch; 
found : Float @scala.util.continuations.cpsParam[sample.Depp,sample.Depp] @scala.util.continuations.cpsSynth 
required: Float @scala.util.continuations.cpsParam[Float,sample.Depp] 
    val res = reset { 
       ^
Float @scala.util.continuations.cpsParam[sample.Depp,sample.Depp] @scala.util.continuations.cpsSynth <: Float @scala.util.continuations.cpsParam[Float,sample.Depp]? 
    scala.util.continuations.cpsParam[sample.Depp,sample.Depp] <: scala.util.continuations.cpsParam[Float,sample.Depp]? 
    Float <: sample.Depp? 
     <notype> <: sample.Depp? 
     false 
    false 
    false 
false 
one error found 

ahh et voici le test: Float <: sample.Depp? il échoue parce que Float est bien sûr pas un sous-type de Depp

question: ne doit pas la règle de transformation alors mieux être donnée:

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

exprimer clairement?

+0

'{shift {(k: Int => Depp) => k (7)}; sepp.asInstanceOf [Float]} 'est typé selon la règle:' Float @ cpsParam [Depp, Depp] '. L'erreur de type que vous voyez est parce que 'reset' s'attend' Float @ cpsParam [Float, Depp] 'et il échoue sur l'argument de la réinitialisation ayant le type incorrect. – huynhjl