Как работает Дотти Десугар полиморфными методами?
Сообщается, что Дотти десагирует классы с параметрами типа в классы с членами типа, например:
class C[T, U] { }
// <=>
class C {
type C$T
type C$U
}
Как Dotty desugar полиморфные методы, как в следующем примере?
def m[T, U](x: T, u: U): T = x
// <=>
?
2 ответа
В отличие от полиморфных классов, полиморфные методы не обессилены. Они в основном остаются полиморфными.
Возможно, вы захотите начать с нижней части страницы 13, раздел 5.2 самой последней статьи DOT "Суть DOT", написанной Нада Амином, Сэмюэлем Грюттером, Мартином Одерским, Тиарком Ромпфом и Сандро Штуки. Показана реализация простого ковариантного полиморфного List[+A]
введите в Scala. Особого внимания заслуживает полиморфный cons[A]
метод:
package scala.collection.immutable
trait List[+A] {
def isEmpty: Boolean
def head: A
def tail: List[A]
}
object List {
def cons[A](hd: A, tl: List[A]) = new List[A] {
def isEmpty = false
def head = hd
def tail = tl
}
}
И как это кодируется в DOT:
let scala_collection_immutable = ν(sci) {
List = μ(self: {A; isEmpty: bool.Boolean; head: self.A; tail: sci.List∧{A <: self.A}})
cons: ∀(x: {A})∀(hd: x.A)∀(tl: sci.List∧{A <: x.A})sci.List∧{A <: x.A} =
λ(x: {A})λ(hd: x.A)λ(tl: sci.List∧{A <: x.A})
let result = ν(self) {
A = x.A; isEmpty = bool.false; head = hd; tail = tl }
in result
}: { μ(sci: {
List <: μ(self: {A; head: self.A; tail: sci.List∧{A <: self.A}})
cons: ∀(x: {A})∀(hd: x.A)∀(tl: sci.List∧{A <: x.A})sci.List∧{A <: x.A}
})}
in …
Что, в свою очередь, должно дать вам интуицию, как она кодируется в Dotty.
Затем на странице 15 показано, как десагрегированный DOT может быть отображен обратно в Scala:
object scala_collection_immutable { sci =>
trait List { self =>
type A
def isEmpty: Boolean
def head: self.A
def tail: List{type A <: self.A}
}
def cons(x: {type A})(hd: x.A)(tl: sci.List{type A <: x.A})
: sci.List{type A <: x.A} = new List{ self =>
type A = x.A
def isEmpty = false
def head = hd
def tail = tl
}
}
Как вы можете видеть, кодировка полиморфного метода более или менее совпадает с полиморфной чертой: параметр типа становится членом абстрактного типа, в данном случае членом абстрактного типа типа уточнения (он же структурный тип):
x : A
// becomes
x : {type A}