どちらの場合も、選択的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:continuations:enable -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オブジェクトがどのようA@cpsParam[A,C]
に存在するかを理解しているのでこれは問題ありません(Tiarkの論文で与えられているリセット機能はそのようなShiftオブジェクトで動作します)
ここで、簡単な例で以下を変更して、デップとは関係のないタイプを生成します。z.asInstanceOf[Float]
これをコンパイルする
scalac -P:continuations:enable -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
ああ、これがテストです: Float <: sample.Depp
?Floatはもちろんサブタイプではないので失敗しますDepp
質問:変換規則は次のように与えられるべきではありません:
e: A@cpsParam[B,C] {[|r|]}: U U <: B
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )
これを明確に表現するには?