我仍然在弄清楚这里涉及的确切打字规则/含义。
如果示例中的类型“足够简单”以“适合”似乎容易/容易,因为在几乎所有简单的示例中都是如此,但在比较事物时它变得更加有趣(至少对我而言)由tiark rompf给出的打字:
|- e: A@cpsParam[B,C]; {[|r|]}: U
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )
因此[|e|].map( (x: A) => {[|r|]} )
的结果将根据tiark的论文中给出的地图定义具有Shift[U,B,C]
类型。
这里U不一定与B相同。
到目前为止,我不明白为什么在没有类似于U<:B的情况下允许U与B不同,在tiark的论文中给出了地图的定义。
我错过了什么,分别在这里没有理解?
任何提示/想法?
答案 0 :(得分:1)
我第二次看这个想看看两种情况下选择性cps变换的结果会产生什么。
我使用了以下简单示例:
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]
,如预期的那样:)
这很好,因为我理解像A@cpsParam[A,C]
这样的Shift对象是如何形成的(Tiark的论文中给出的重置函数对这样的Shift对象进行操作)
现在更改简单示例中的以下内容以生成与Depp无关的类型: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|]} )
清楚地表达这个?