Why does Scala compiler say that contravariant type A occurs in covariant position in type >: A <: Any of type B?

StackOverflow https://stackoverflow.com/questions/14678518

Question

The compiler is telling me this can't be with a warning of: "contravariant type A occurs in covariant position in type >: A <: Any of type B." The warning is in the type parameter of the compose method. Logically the type definition makes sense to me. If the compiler has no qualms with andThen, why the problem with the converse?

trait Foo[-A]{
  def compose[B >: A](t: Foo[B]): Foo[A] = t andThen this
  def andThen[B <: A](t: Foo[B]): Foo[B]
}

All I need is an example where it breaks down. Then I'm happy.

Was it helpful?

Solution

As the error says, your variance annotation of A is wrong. You cannot use A in a return type which is a covariant position. Imagine you had another method in Foo which uses A in proper contravariant position (as an argument):

trait Foo[-A] {
  ...
  def foo(a: A): Unit
}

Now you can see how this crashes:

  • Foo[-A] implies that Foo[X] <: Foo[Y] if X >: Y
  • a returned value may be a subtype of the declared return type
  • therefore, if -A was legal here, compose might return a Foo[A1] for some A1 >: A
  • say trait X and trait Y extends X { def bar() }
  • imagine a Foo[Y] where foo calls a.bar()
  • consequently it would break if compose was allowed to return Foo[X]

So for you example to compile, A must be invariant.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top