0

As per the definition of contravariance (super class instances will be accepted), my last statement in the below code snippet, should be accepted; but it is thrown with type error. Can you please correct my understanding.

  class A
  class B extends A
  class C extends B
  
  abstract class Box[-T] {
     def set(x : T) :Unit
  }
  
  val x = new Box[B] {
    def set(b:B) = Console println "B"
  }
  
  val y  = new Box[A] {
    def set(a:A) = Console println "A"
  }
  
  val z  = new Box[C] {
    def set(c:C) = Console println "C"
  }  

  x.set(new A)   <-- Type error

But x.set(new C) is fine! So even though "contravariant parameters are accepted as method parameters" is in fact, are covariant parameters actually.

user3103957
  • 636
  • 4
  • 16
  • 1
    As the answers have pointed out, you are misunderstanding contravariance. Here's a snippet that does demonstrate it, given your example: `def foo(b: Box[B]) = b.set(new B); foo(y) // prints A` – slouc Nov 13 '20 at 17:38
  • 2
    Notice that the results you're seeing are the same if you remove the `-` from `T`. What you're seeing has nothing to do with the variance setting of `T`. – jwvh Nov 13 '20 at 17:43

2 Answers2

2

You are confusing how contravariance works. x is a Box[B] as such, set accepts values of type B (or any subtype of B because that is what Liskvo says).

However, Box[A] is a subtype of a Box[B]. So you could have passed y where x is expected. Because a Box that can store any A can store a B.
But, a Box that can store only Bs can not store and arbitrary A.

2

It looks like this not how it would work and that's from a conceptual stand point: a B is an A but not the other way around.

As indicated in the scala doc for variances, contravariant type parameters allow to pass a "super-type" instead of the "sub-type", but this applies to what is used within the body (e.g. If the "super-type" already has defined what's used) otherwise I guess it just considers the type and we're back to what I explained before.

Vivick
  • 3,434
  • 2
  • 12
  • 25