0

I have a question about Scala variances.

The code below is valid code, which passes compile.

// <Code A> 
// VALID (COMPILE PASS!)
class A[+T, -U](t: T, u: U)

But the code below is not valid, which use val and doesn't pass compile.

// <Code B>
// INVALID (COMPILE ERROR)
class A[+T, -U](val t: T, val u: U)

The error message is the following.

error: contravariant type U occurs in covariant position in type => U of value u
class A[+T, -U](val t: T, val u: U)
                                 ^

I wonder why <Code A> is valid and <Code B> isn't valid. Could someone tell me the reason?

ryo
  • 2,009
  • 5
  • 24
  • 44

1 Answers1

2

You've declared U to be contravariant (that's what -U means). Another way of thinking about contravariance is that it's an "input type". ie. The type can be used as a parameter for methods, but not as a return value.

By declaring it as a val, it's now accessible outside of the class as an "output value". This breaks the rule of contravariance.

If you wish to make U a val, you must either make it covariant (+U) if possible, or if you need it to be an input as well it must be made invariant.

puhlen
  • 8,400
  • 1
  • 16
  • 31