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