Consider this simple example:
trait Optimizer[+FParam, FRes] {
def optimize(
fn: (FParam) => FRes,
guesses: Seq[FParam] // <--- error
)
}
It doesn't compile, because
Covariant type
FParam
occurs in contravariant position in typeSeq[FParam]
of value guesses.
But seq is defined as trait Seq[+A]
, so what is the source of this contravariance? (Question 1)
Conversely, consider this simple example with -FParam
:
trait Optimizer[-FParam, FRes] {
def optimize(
fn: (FParam) => FRes, // <--- error
guesses: Seq[FParam]
)
}
Contravariant type occurs in covariant position in type
(FParam) => FRes
Again, the same paradox: in Function1[-T1, R]
, the first type parameter is clearly contravariant, so why is FParam
in a covariant position? (Question2)
I can fix this issue by flipping the variance as described in Lower type bounds, but why it is necessary is unclear.
trait Optimizer[+FParam, FRes] {
type U <: FParam
def optimize(
fn: (FParam) => FRes,
guesses: Seq[U]
)
}