Scala Language Type Variance Covariance of a collection


Example

Because collections are typically covariant in their element type*, a collection of a subtype may be passed where a super type is expected:

trait Animal { def name: String } 
case class Dog(name: String) extends Animal

object Animal {
  def printAnimalNames(animals: Seq[Animal]) = {
    animals.foreach(animal => println(animal.name))
  }
}

val myDogs: Seq[Dog] = Seq(Dog("Curly"), Dog("Larry"), Dog("Moe"))

Animal.printAnimalNames(myDogs)
// Curly
// Larry
// Moe

It may not seem like magic, but the fact that a Seq[Dog] is accepted by a method that expects a Seq[Animal] is the entire concept of a higher-kinded type (here: Seq) being covariant in its type parameter.

* A counterexample being the standard library's Set