Недавно я заметил, что аннотации дисперсии можно использовать в псевдонимах типов, вот пример из Predef
] :
type Function[-A, +B] = Function1[A, B]
И Я стал думать, где это можно использовать. Очевидно, вы не можете изменить дисперсию на противоположность или заставить инвариантный тип вести себя как ко- или контравариантный. Компилятор выдаст ошибку, подобную этой
scala> type BrokenFunc[+T, -R] = Function1[T, R]
<console>:7: error: covariant type T occurs in contravariant position in type
[+T, -R]T => R of type BrokenFunc
Но вы можете заставить какой-то вариантный тип вести себя как инвариантный (по крайней мере, компилятор с этим не поспорит). Итак, я попытался сделать инвариантную версию List
scala> type InvList[T] = List[T]
defined type alias InvList
. Но этот новый инвариант List
по-прежнему ведет себя так же, как и исходная ковариантная версия:
scala> val l: InvList[String] = List("foo")
l: InvList[String] = List(foo)
scala> val anyList: InvList[Any] = l
anyList: InvList[Any] = List(foo)
Итак, что я упускаю? Какова цель аннотаций дисперсии в псевдонимах типов? Можете ли вы привести пример псевдонима типа с аннотациями дисперсии, который будет отличаться от исходного типа.