How to understand the two sentences about "Covariance" and "Contravariance"?

250 views Asked by At

I'm reading the first section of "Scala in depth", there are two sentences in the first section about "covariance" and "contrvariance":

Covariance (+T or ? extends T) is when a type can be coerced down the inheritance hierarchy.

Contravariance(-T or ? super T) is when a type can be coerced up the inheritance hierarchy.

I have read some documents about "Covariance" and "Contravariance", but I can't understand the word "coerced down" and "coerced up" here in this context.

3

There are 3 answers

2
Golly On BEST ANSWER
[TOP / ABSTRACT]

Thing
  ↓
Animal
  ↓
Human
  ↓
Programmer
  ↓
Scala Dev

[BOTTOM / SPECIFIC]

Covariance: Accept T or lower.
I asked for a [+Human], I will accept any of these: [Human, Programmer, Scala Dev].

Contravariance: Accept T or higher.
I asked for a [-Human], I will accept any of these: [Thing, Animal, Human].

Inariance: Accept T and only T.

Coercion.
Coercing a type up/down the type hierarchy means checking that a type's super/sub type passes type constraints. For example, a covariant function needs a Human but we've only got a Programmer, that's ok, the compiler can coerce the Programmer into Human to satisfy typing constraints.

0
Momog On

This response is taken from lectures given by Martin Odersky (the creator of Scala) on Coursera. We note:

S<:T means: S is a subtype of T, and
S>:T means: S is a supertype of T, or T is a subtype of S.

Say C[T] is a parameterized type and A, B are types such that A<:B. In general there is three possible relationships between C[A] and C[B]:

C[A]<:C[B] ---------> C is covariant
C[A]>:C[B] ---------> C is contravariant
neither C[A] nor C[B] is a subtype of the other ---------> C is nonvariant

Scala lets you declare the variance of a type by annotating the type parameter:

class C[+A] { ... }  ---------> C is covariant
class C[-A] { ... } ----------> C is contravariant
class C[A]  { ... } ----------> C is nonvariant

Hope this might help!

0
iain On

In this case coerced means the compiler can treat the type as a type further up/down the inheritance hierarchy.

Think of it as upcasting or downcasting except the compiler is doing it automatically, so it is not a cast (which could suggest that explicit code was required to perform it).