I understand the terms co-variance and contra-variance. But there is one small thing I am unable to understand. In the course "Functional Programming in Scala" on coursera, Martin Ordersky mentions that:
Functions are contravariant in their argument types and co-variant in their return types
So for example in Java, let Dog
extends Animal
. And let a function be :
void getSomething(Animal a){
and I have the function call as
Dog d = new Dog();
getSomething(d)
So basically what is happeneing is that Animal a = d
. And according to wiki covariance is "Converting wider to narrow". And above we are converting from dog to Animal. SO isnt the argument type covariant rather than contravariant?
Covariance and contravariance are terms that refer to the ability to use a more derived type (more specific) or a less derived type (less specific) than originally specified. Generic type parameters support covariance and contravariance to provide greater flexibility in assigning and using generic types.
Covariance means that a method can return a type that is derived from the delegate's return type. Contra-variance means that a method can take a parameter that is a base of the delegate's parameter type.
This is how functions are defined in Scala:
trait Function1 [-T1, +R] extends AnyRef
In English, parameter T1
is contravariant and result type R
is covariant. What does it mean?
When some piece of code requires a function of Dog => Animal
type, you can supply a function of Animal => Animal
type, thanks to contravariance of parameter (you can use broader type).
Also you can supply function of Dog => Dog
type, thanks to covariance of result type (you can use narrower type).
This actually makes sense: someone wants a function to transform dog to any animal. You can supply a function that transforms any animal (including dogs). Also your function can return only dogs, but dogs are still animals.
Converting Dog
to Animal
is converting narrow to wider, so it's not covariance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With