Для простого случая, когда A
и B
связаны компилятором в то же время, что и T
, Ответ IttayD работает нормально:
def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
КогдаA
и B
уже связаны, как в вашем примере class Foo[A, B]
, вам нужно ввести временные фиктивные переменные, чтобы компилятор выполнял эту работу:
class Foo[A, B](a: A, b: B) {
def g[T, A1 >: A <: T, B1 >: B <: T] = List[T](a: A1, b: B1)
}
(Радиясность: A1 >: A <: T
означает, что тип A1
должен быть супертипом A
и подтипом T
, а не то, что A
является подтипом обоих A1
и T
.)
A1
и B1
здесь с единственной целью определить правильный тип для T
.Если компилятор должен вывести их, они преобразуются в A1 = A
и B1 = B
, а затем T
в качестве наиболее определенного типа, который является суперклассом A
и B
.
Одна вещь, которую компилятор не осознает, это то, что благодаря транзитивности у нас есть и T >: A
, и T >: B
, что следует непосредственно из ограничений относительно A1
и B1
.Нам нужно помочь с надписями типов.
Теперь Product#productIterator
не может использовать эту технику, так как она определена в месте, где мы даже не знаем A
и B
, или на самом делесколько параметров типа в конкретном подклассе.