Существующие типы для 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 Если вы можете объяснить, почему принятый в настоящее время ответ работает, то есть почему компилятор не может определить, что тип допустим без надписи.

1 ответ

Решение

Я думаю, компилятору нужна помощь. Следующее должно работать:

val l2 = List[SomeA](b, c: Ter, d)
Другие вопросы по тегам