Я еще раз посмотрел на это, так как хотел посмотреть, что результат избирательного преобразования cps даст в обоих случаях.
- U <: B </li>
- 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: продолжения: enable -Xprint: selecps 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, как A@cpsParam[A,C]
(функция сброса, приведенная в статье Тиарка, работает с такими объектами Shift)
Теперь изменим следующее в простомПример для получения типа, не связанного с Деппом: z.asInstanceOf[Float]
, компилируя это с
scalac -P: продолжения: enable -Xprint: seleccps -explaintypes.до следующей ошибки, которая телВот что на самом деле проверено:
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
ааа, а вот тест: Float <: sample.Depp
?таким образом, это терпит неудачу, потому что Float, конечно, не является подтипом Depp
вопрос: разве не лучше было бы тогда дать правило преобразования как:
e: A@cpsParam[B,C] {[|r|]}: U U <: B
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )
, чтобы ясно выразить это?