2010-11-16 5 views
2

Я все еще в процессе выяснения точных правил/последствий ввода, которые здесь присутствуют.scala delimited continue typing

Похоже, что типы в примерах «достаточно просты» для «хорошо подходят», как это происходит практически во всех простых примерах, но это становится более интересным/трудным (по крайней мере для меня) при сравнении вещи для типирования заданной tiark rompf:

|- e: [email protected][B,C]; {[|r|]}: U 
----------------------------------------------------- 
[|val x: A = e; r|] = [|e|].map((x: A) => {[|r|]}) 

поэтому результат [|e|].map((x: A) => {[|r|]}) будет иметь тип Shift[U,B,C] в соответствии с определением карты, приведенной в статье tiark в.

Здесь U не обязательно совпадает с В.

До сих пор я не понимаю, почему U разрешено отличаться от B, не что-то вроде U <: B дано в определении карты в бумажном tiark в.

Что мне не хватает, соответственно, не понимая здесь?

Любые советы/идеи?

ответ

1

У меня был второй взгляд на это, так как хотелось увидеть, какой результат избирательного преобразования cps даст в обоих случаях.

  1. U <: B
  2. 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|]}) 

ясно выразить это?

+0

'{shift {(k: Int => Depp) => k (7)}; sepp.asInstanceOf [Float]} 'вводится в соответствии с правилом как:' Float @ cpsParam [Depp, Depp] '. Ошибка типа, которую вы видите, заключается в том, что 'reset' ожидает' Float @ cpsParam [Float, Depp] ', и он терпит неудачу в аргументе сброса, имеющем неправильный тип. – huynhjl