scala variance

Variance allows sub-typing of generic generic classes.

class Box[T](var content: T)

Box[T] is a generic class with type T.

abstract class Animal:
    val name: String
 
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal

Cat is a subtype of Animal, similarly Dog.

Is Box[Cat] subtype of Box[Animal]? It should be.

val cat: Cat = Cat("Whisky")
val catBox: Box[Cat] = Box[Cat](cat)
val animalBox: Box[Animal] = Box[Animal](cat)
 
animalBox.content
// cat

But

val animalBox: Box[Animal] = catBox 
 
// gives compilation error

So, Box[Animal] and Box[Cat] don’t have sub-typing relationship.

Scala provides three types of variances viz Invariance, Covariance and Contra variance.

By default it is invariance as exampled shown above.

References

  1. Variances Scala book