Это происходит потому, что Scala не имеет union типов, как type T = String | Long
. Ваш T
от List[T]
должен иметь некоторый конкретный тип, например String
, Long
или что-то, и вы не можете создать список из нескольких типов. Каждый элемент в списке должен иметь тот же тип T
, что делает много операций (например, flatMap
или filter
), чтобы можно:
scala> val a: (Int, Int, String, String, Int) = parseSomething() // tuple may be seen as List with heterogenous elements
a: (Int, Int, String, String, Int) = (5, 6, "a", "b", 7)
scala> val b = a.filter(_ != 6) //how compiler would know that `a._2 == 6` to infer (Int, String, String, Int) ?
b: (???) = (5, "a", "b", 7)
Так T
должно быть одинаковым для всех элементов. Когда компилятор видит несколько параметров, которые имеют несколько типов, он пытается найти ближайший общий тип:
def ff[T](a: T, b: T): T = a
trait A
case class A1() extends A
case class A2() extends A
scala> ff(A1(), A2())
res20: A = A1() //A is the nearest common type
Дженерик немного интереснее. Компилятор может вывести экзистенциальный тип для них M[_ >: A1 with A2]
:
scala> ff(new LongHolder(1), new StringHolder("a"))
res23: Holder[_ >: String with Long] = [email protected]
Это означает Holder[T] forSome {type T >: String with Long}
, что означает, что Holder
определяется для некоторого T
(например T
должен существовать но не обязательно для всех держателей), которые >: String with Long
. Просто говоря, компилятор спрашивает: «Эй! Нам нужны некоторые T
, что больше, чем Int с Long здесь» (представьте себе типы, как коробки, чтобы положить что-то в, и компилятор просто «Бригадир»)
Наконец Any
меньше (ближе) (он подходит, как он может быть больше String with Long
), поэтому результат становится Any
, так как само значение не может быть экзистенциальным в Scala.
P.S. Shapeless HList
на самом деле делает то, что вы хотите.
Тип стирания не имеет ничего общего с этим, поскольку тип становится «потерянным» во время компиляции - не во время выполнения – dk14
Вы правы, и ваше объяснение довольно ясно об этом. Я отредактировал свой ответ и надеюсь, что он по-прежнему содержит полезную информацию. – ipoteka