Существующие типы для F-ограниченных полиморфных типов и неуниверсальных подтипов?
У меня есть два подтипа, которые я должен быть F-ограниченным полиморфным по типуA
и подтип одного из этих подтипов, т.е.
trait A[T <: A[T]] {
def x: T
}
trait Ter extends A[Ter]
trait For extends A[For]
trait C extends Ter
Далее я пытаюсь реализовать конкретный тип
case class F2(l: List[A[_]]) extends For {
def x: For = F2(l.map(_.x))
}
Но это не компилируется с:
<console>:11: error: type mismatch;
found : List[Any]
required: List[A[_]]
def x: For = F2(l.map(_.x))
^
Итак, Google говорит, что мне нужно использовать экзистенциальные типы, что имеет смысл, поэтому я пытаюсь:
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))
}
Но теперь я сталкиваюсь с новой проблемой, когда пытаюсь
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)
}
Ошибка компиляции:
<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)
^
Почему я получаю эту ошибку? конечноC
это подтипTer
что, в свою очередь, является подтипомA[Ter]
, следовательноC
это подтипA[Ter]
следовательно, существуетT
а именноTer
такой, чтоC
это подтипA[T]
, следовательноC
это подтипSomeA
.
Как будто транзитивность подтипа не работает. Когда я взломать это сc.asInstanceOf[SomeA]
мой код компилируется, и мои модульные тесты проходят. Может ли это быть ошибка компилятора?
Я тоже думал чтоList[A[_]]
был сильнее печатать, чемList[SomeA]
то есть первый говорил, что список состоит изA[T]
немногофиксированный типT
где последний говорит, что список состоит изA[T]
гдеT
являетсяне фиксируется.
Bouns Если вы можете объяснитьЗачем принятый в настоящее время ответ работает, то есть, почему компилятор не может определить, что тип допустим без указания.