Продолжение набора текста с разделителями на скалах - PullRequest
2 голосов
/ 16 ноября 2010

Я все еще нахожусь в процессе выяснения точных правил / значений печатания, вовлеченных здесь.

Кажется, легко / легче, если типы в примерах "достаточно просты", чтобы "хорошо вписаться", как это происходит почти во всех простых примерах, но это становится более интересным / трудным (по крайней мере для меня) при сравнении на набор текста, данный tiark rompf:

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

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

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

Пока я не понимаю, почему U может отличаться от B без чего-то вроде U <: B, указанного в определении карты в статье Тиарка. </p>

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

Какие-нибудь советы / идеи?

1 Ответ

1 голос
/ 23 ноября 2010

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

  1. U <: B </li>
  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: продолжения: 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|]} )

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

...