Variance in Scala

"Variance" describes the subtyping relationship between types. In scala, the possiblities are: covariance, contravariance and invariance.

Covariance allows the type to be more specific. For example, if A is a substype of B -> then F[A] is also a subtype of F[B]. A more concrete example:


        class Animal
        class Dog extends Animal
  
        class Container[+T](value: T){ getValue: T = valule }
  
        val animalContainer: Container[Animal] = new Container(new Dog) // this is valid!
      

contravariance allows a subtype to be more general. For example: if A is a subtype of B -> F[B] is also a subtype of F[A]


        class Printer[-T] { def print(value: T): Unit = println(value) }
  
        val dogPrinter: Printer[Dog] = new Printer[Animal]
      

Invariant is neither covariant OR contravariant