Ответ 1
Ну, просто, это имеет смысл? Подумайте о замене Лискова.
ковариационной
Если A <: B
, имеет смысл передать a C[A]
, где ожидается a C[B]
? Если да, сделайте это C[+T]
. Классическим примером является неизменяемый List
, где a List[A]
можно передать любому ожидающему List[B]
, предполагая, что A
является подтипом B
.
Два примера счетчика:
Переменные последовательности являются инвариантными, так как в противном случае возможно иметь нарушения безопасности типа (на самом деле Java-вариант Array
уязвим только для таких вещей, поэтому он инвариантен в Scala).
Неизменяемый Set
инвариантен, хотя его методы очень похожи на методы неизменяемого Seq
. Разница заключается в contains
, который набирается на множествах и нетипизируется (т.е. Принимает Any
) на последовательности. Таким образом, несмотря на то, что в противном случае было бы возможно сделать его ковариантным, стремление к повышенной безопасности типов по конкретному методу привело к выбору инвариантности по сравнению с коразмерностью.
Контра-дисперсия
Если A <: B
, имеет смысл передать a C[B]
, где ожидается a C[A]
? Если да, сделайте это C[-T]
. Классическим примером является Ordering
. Хотя некоторые несвязанные технические проблемы не позволяют Ordering
быть противоречивыми, интуитивно понятно, что все, что может заказать суперкласс класса A
, также может заказать A
. Из этого следует, что Ordering[B]
, который упорядочивает все элементы типа B
, супертип A
, может быть передан чему-то ожидающему Ordering[A]
.
Пока Scala Ordering
не является контравариантным, Scalaz Order является противоречивым, как ожидалось. Другим примером из Scalaz является его Equal.
Смешанная разность?
Наиболее заметным примером смешанной дисперсии в Scala является Function1
(и 2, 3 и т.д.). Это противоречиво в параметре, который он получает, и ко-вариант в том, что он возвращает. Обратите внимание, однако, что Function1
- это то, что используется для многих закрытий, а замыкания используются во многих местах, и эти места обычно используются там, где Java использует (или использует) классы Single Abstract Method.
Итак, если у вас есть ситуация, когда применяется класс SAM, это, скорее всего, место для смешанной противоречивости и ковариации.