Covariance and contravariance are qualities of the class not qualities of the parameters. (They are qualities that depend on the parameters, but they make statements about the class.)
So, Function1[-A,+B]
means that a function that takes superclasses of A
can be viewed as a subclass of the original function.
Let’s see this in practice:
class A
class B extends A
val printB: B => Unit = { b => println("Blah blah") }
val printA: A => Unit = { a => println("Blah blah blah") }
Now suppose you require a function that knows how to print a B
:
def needsB(f: B => Unit, b: B) = f(b)
You could pass in printB
. But you could also pass in printA
, since it also knows how to print B
s (and more!), just as if A => Unit
was a subclass of B => Unit
. This is exactly what contravariance means. It doesn’t mean you can pass Option[Double]
into printB
and get anything but a compile-time error!
(Covariance is the other case: M[B] <: M[A]
if B <: A
.)