sealed trait Sum[+A, +B] {
def flatMap[A, C](f: B => Sum[A, C]): Sum[A, C] =
this match {
case Failure(v) => Failure(v)
case Success(v) => f(v)
}
}
Isn't it said that function parameters are contra-variant and the results co-variant? Why does the compiler say that A is in a contra-variant position? I am expecting compiler to complain that B is in a contra-variant position instead.
Can someone explain to me why this is so ? Feeling confused.
I assume you actually meant to write:
Take a look at
flatMapagain:Let's rewrite it a bit:
Let's build up the type from the inside out.
Ais a parameter toSum, which is normally a covariant position.Sum[A, C]is the result of a function, which is normally a covariant position. These two combine, and you haveAin a covariant position still.B => Sum[A, C]is also the parameter of a function, so the entire thing is in contravariant position. SinceAwas in a covariant position before, the variances combine andAis now in a contravariant position.Looking at
B:Parameter of a function, which is normally a contravariant position.
The entire function is also the parameter to another function, so the contravariances cancel out and
Bis sitting in a covariant position.You can also draw a nifty analogy. Look at the definition of a covariant and contravariant type parameter:
They look like positive and negative numbers, just a bit. Now, remember the rules for multiplication and signs you learned in elementary:
(+) * (+) = (+)(+) * (-) = (-)(-) * (+) = (-)(-) * (-) = (+)This is analogous to (if you squint a bit)
Co[Co[A]]=>Ais in a covariant positionCo[Con[A]]=>Ais in a contravariant positionCon[Co[A]]=>Ais in a contravariant positionCon[Con[A]]=>Ais in a covariant position.