1

I am unable to understand contravariance wrt functiontype 1. The definition of function type1 is as below :

Function1(-T,+T)

The definition clearly says the input type parameter is contravariance. So a superclass type of a type should be allowed as parameter. But why is this giving compiler error.

I have defined below classes

 class Animal 
  class Mammal extends Animal 
  class Cow extends Mammal  

I have defined method as below

def move(m:Mammal) = Unit c 

When I am invoking move like in below it gives no error

 move (new Cow) 

but this gives error

move(new Animal)

Why is that I am not able invoke move() with Animal as param even though Function1 is contravariant[-T] .

I am new to Scala, so please help me out in this

Anveshan
  • 614
  • 1
  • 9
  • 21
  • 1
    Possible duplicate of [Isn't the argument type co- not contra-variant?](http://stackoverflow.com/questions/13321921/isnt-the-argument-type-co-not-contra-variant) – Johny T Koshy Nov 08 '15 at 08:00

2 Answers2

2

Contravariance does not mean that the function can be provided with a value of "lower" type, but that when comparing the types of two functions

type F = Function1(A, B)
type G = Function1(C, B)

then if A is a super type of C then F is a sub type of G. In essence, the ordering (variance) on types of functions goes against (contra) the ordering of the types in their input positions.

In particular if you imagine a function:

def foo(f : Cow => String) : String = f(new Cow)

Then from the perspective of the body of foo, f can accept a Cow, but then, from the perspective of the caller to foo, a function that accepts Animal would also accept Cow just fine, so it makes sense to allow that:

foo((a : Animal) => "generic animal noise")
foo((c : Cow) => "moo")

In English, the contract for the function foo is:

Give me a thing that when I provide it a Cow, I get given back a String, and in return, I will give you a String.

And in particular, a function that when given an Animal provides a String, fits the bill for "a thing that when given a Cow, returns a String".

amnn
  • 3,657
  • 17
  • 23
0

Actually, the nature of can be intuitively understood: you cannot pass instance of Animal to move, because function move may rely on some method which is defined in Mammal but is missing in Animal.

Hope this helps

Nyavro
  • 8,806
  • 2
  • 26
  • 33