As asked
Walk me through covariance and contravariance in Scala. When would you mark a type parameter as +A versus -A, and what does the compiler actually enforce when you do that?
Sample answer outline
A strong answer explains that +A means the type constructor is covariant, so List[Cat] is a subtype of List[Animal], while -A means contravariant, so Function1[-A, +B] accepts a wider input type. The candidate should explain that the compiler enforces positions: covariant type params can only appear in output positions, contravariant only in input positions. Bonus for mentioning invariance in mutable containers like Array[A] and why mutation breaks the substitution principle.
Expect these follow-ups
- Why is Array[T] invariant in Scala even though List[+T] is covariant?
- How does variance interact with bounds, like +A <: Animal?