Search code examples
scalavariance

What is the variance of argument types in Scala?


I've read about Scala having covariant return types for functions. But what about its argument types? What does FunctionX(T1,...,R) have to do with all this?


Solution

  • If you look at the documentation for any FunctionX class, you'll see that the return type is co-variant and the argument types are contravariant. For instance, Function2 has the signature:

    Function2[-T1, -T2, +R] extends AnyRef
    

    You can spot the - and + before the type parameters, where - means contravariant and + covariant.

    This means that given

    class Animal
    class Dog extends Animal
    

    then

    Function1[Animal, Dog] <: Function1[Dog, Dog]
    Function1[Dog, Dog] <: Function1[Dog, Animal]
    

    but

    Function1[Dog, Animal] </: Function[Dog, Dog]
    Function1[Animal, Animal] </: Function[Animal, Dog]
    

    In other words, functions promise no less and require no more