0Pricing
Scala for Backend Engineering & Functional Programming · Lesson

Variance: Covariance & Contravariance

Master covariance and contravariance to correctly handle subtyping relationships in generic types.

What is Type Variance?

In Scala, when you have a type hierarchy (e.g., Cat is a subtype of Animal), how do generic types behave?

Is a List[Cat] considered a subtype of List[Animal]? Not always by default!

Type variance allows us to define how subtyping relationships are preserved (or reversed) for generic types. This is crucial for writing flexible and type-safe code.

Covariance: 'Producer' Types (+T)

Covariance is denoted by placing a + before the type parameter (e.g., trait Box[+T]).

  • If A is a subtype of B, then Box[A] becomes a subtype of Box[B].
  • Think of covariant types as 'producers' of T. They can only appear in output positions (like return types of methods).
  • This means if you expect a Box[Animal], a Box[Cat] can be provided because it 'produces' something more specific (a Cat is an Animal).

All lessons in this course

  1. Generics and Type Parameters
  2. Variance: Covariance & Contravariance
  3. Type Classes and Implicits
← Back to Scala for Backend Engineering & Functional Programming