scala分隔继续打字

时间:2010-11-16 20:42:11

标签: scala continuations

我仍然在弄清楚这里涉及的确切打字规则/含义。

如果示例中的类型“足够简单”以“适合”似乎容易/容易,因为在几乎所有简单的示例中都是如此,但在比较事物时它变得更加有趣(至少对我而言)由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的论文中给出了地图的定义。

我错过了什么,分别在这里没有理解?

任何提示/想法?

1 个答案:

答案 0 :(得分:1)

我第二次看这个想看看两种情况下选择性cps变换的结果会产生什么。

  1. U<:B
  2. U不是B
  3. 的子类型

    我使用了以下简单示例:

    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|]} )
    

    清楚地表达这个?