У меня был второй взгляд на это, так как хотелось увидеть, какой результат избирательного преобразования cps даст в обоих случаях.
- U <: B
- U не является подтипом B
Я использовал следующий простой пример:
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)
}
Сборка это с помощью
scalac -P : продолжение: включить -Xprint: selectivecps Sample.scala
оказывается успешным и приводит к следующему (интересная часть только):
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
}))
ИТАК тип результирующего (применение карты) объекта Shift, это [Sepp,Depp,Depp]
как ожидалось :)
это хорошо, потому что я понимаю, как возникают объекты Shift, такие как [email protected][A,C]
(функция сброса, данная в бумаге Тирка, работает на таких объектах Shift)
Теперь изменим следующее на простом примере, чтобы получить тип, не имеющий отношения к Depp: z.asInstanceOf[Float]
компиляции это с
scalac -P: продолжений: включить -Xprint: selectivecps -explaintypes Sample.scala
выводит следующее сообщение об ошибке, которое говорит, что на самом деле проверяется:
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 и вот тест: Float <: sample.Depp
? так это не удается, потому что Float, конечно, не является подтипом Depp
вопрос: должен ли не правилом преобразования, то лучше быть дано как:
e: [email protected][B,C] {[|r|]}: U U <: B
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map((x: A) => {[|r|]})
ясно выразить это?
'{shift {(k: Int => Depp) => k (7)}; sepp.asInstanceOf [Float]} 'вводится в соответствии с правилом как:' Float @ cpsParam [Depp, Depp] '. Ошибка типа, которую вы видите, заключается в том, что 'reset' ожидает' Float @ cpsParam [Float, Depp] ', и он терпит неудачу в аргументе сброса, имеющем неправильный тип. – huynhjl