Existentielle Typen für F-begrenzte polymorphe Typen und nicht generische Subtypen?
Ich habe zwei Untertypen, die ich durch einen Typ F-begrenzt polymorph sein mussA
und ein Subtyp eines dieser Subtypen, d. h.
trait A[T <: A[T]] {
def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter
Nächste Ich versuche, einen konkreten Typ zu implementieren
case class F2(l: List[A[_]]) extends For {
def x: For = F2(l.map(_.x))
}
Aber dies kann nicht kompiliert werden mit:
<console>:11: error: type mismatch;
found : List[Any]
required: List[A[_]]
def x: For = F2(l.map(_.x))
^
Also, Google sagt, dass ich existenzielle Typen verwenden muss, was Sinn macht, also versuche ich:
import scala.language.existentials
type SomeA = T forSome { type T <: A[T] }
case class F1(l: List[SomeA]) extends For {
def x: For = F1(l.map(_.x))
}
Aber jetzt stoße ich auf ein neues Problem, wenn ich versuche, @ zu instanziier
trait Example {
val b: Ter
val c: C
val d: For
// Works fine
val l1: List[A[_]] = List(b, c, d)
// But this doesn't work, fails to compile (see below)
val l2: List[SomeA] = List(b, c, d)
val f1 = F1(l2)
}
Der Kompilierungsfehler:
<console>:22: error: type mismatch;
found : C
required: SomeA
(which expands to) T forSome { type T <: A[T] }
val l2: List[SomeA] = List(b, c, d)
^
Warum erhalte ich diesen Fehler? SicherC
ist ein Subtyp vonTer
, was wiederum ein Subtyp von @ iA[Ter]
, deshalbC
ist ein Subtyp vonA[Ter]
, daher gibt es einT
nämlichTer
so dassC
ist ein Subtyp vonA[T]
, deshalbC
ist ein Subtyp vonSomeA
.
Es ist, als ob die Transitivität der Subtypisierung nicht funktioniert. Wenn ich es mit @ hacc.asInstanceOf[SomeA]
Mein Code wird kompiliert und meine Komponententests bestehen. Könnte es sich um einen Compiler-Fehler handeln?
Ich dachte auch, dassList[A[_]]
war eine stärkere Eingabe alsList[SomeA]
, d. h. der erstere sagte, dass die Liste aus @ besteA[T]
etwasFes ArtT
, wo letztere sagt, dass die Liste aus @ besteA[T]
woT
istnicht behobe.
BOUNS Wenn du erklären kannstWaru die aktuell akzeptierte Antwort funktioniert, d. h. warum der Compiler nicht herausfinden kann, dass der Typ ohne die Zuweisung gültig ist.