Этот код компилируется так же, как хорошо:Тип псевдонима A не эквивалентен A?
type Named[A] = (String, A)
def foo[A](a: A) = {}
trait Elem[A]
val m = Map[String, Elem[_]]()
m.foreach(e => foo[Named[Elem[_]]](e))
Однако это один не делает:
type NamedElem[A] = Named[Elem[A]]
m.foreach(e => foo[NamedElem[_]](e))
Сообщение об ошибке не объясняет, почему:
type mismatch;
found : (String, Elem[_])
required: NamedElem[_]
(which expands to) (String, Elem[_$2]) forSome { type _$2 }
Map[String, Elem[_]]().foreach(e => foo[NamedElem[_]](e))
^
Таким образом, очевидно NamedElem[A]
не Named[Elem[A]]
. Это предполагаемое поведение? Или я чего-то не хватает?
Спасибо!
Спасибо @ dk14, поэтому 'Названа [Эль [A]]' не 'NamedElem [A]' 'когда A' экзистенциальный тип , Как вы думаете, мы можем предотвратить эту разницу? Я имею в виду, есть ли способ объявить 'тип NamedElem [A]', который полностью эквивалентен 'Named [Elem [A]]'? –
@ RyoichiroOka Это _is_ эквивалентно для каждого типа 'A'. Проблема в том, что '_' не является типом. –
Существует только способ объявления соответствующих экзистенциальных (если они вам действительно нужны) - 'type NamedElem_ = Named [Elem [T] forSome {type T}]'. Как сказал Алексей Романов, это уже эквивалентно для непиковых дженериков. Попытка унифицировать его не имеет смысла ... просто посмотрите на desugaring - '_' - это всего лишь синтаксис сахара на' forSome', а не тип сам. Определение экзистенциального типа здесь '{type T}' inside 'forSome', даже' T' внутри 'Elem [T]' (это просто ref) – dk14