I believe one can define covariance (at least, for objects) as \'the ability to use a value of a narrower (sub) type in place of a value of some wider (super) type\', and th
A simplified explanation
class A
class B extends A
val printA: A => Unit = { a => println("Blah blah blah") }
printA(new A()) //"Blah blah blah"
printA(new B()) //"Blah blah blah"
contravariance rule:
If B is a subtype of A, then printA[A] is a subtype of printA[B]
Since printA[B] is the superclass, we can use printA(new B())