Why is Function[-A1,...,+B] not about allowing any supertypes as parameters?
contravariance, covariance, function, scala
Solution
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`.)
Problem
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 that contravariance is the exact opposite of this. Apparently, Scala functions are instances of Function[-A1,...,+B] for contravariant parameter types A1, etc. and covariant return type, B. While this is handy for subtyping on Functions, shouldn't the above definition mean I can pass any supertypes as parameters? Please advise where I'm mistaken.