问题
In Option we have
def getOrElse[B >: A](default: => B): B = this match {
case None => default
case Some(a) => a
}
def orElse[B >: A](obj: => Option[B]): Option[B] = this match {
case None => obj
case _ => this
}
In Either we have:
def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B]
I understand what is going and why, a rather extended example could be this
OrElse( { Option[B]}).map{....} If B is such that A :> B, then if Some(a) you get Some(a).map(f:B => ???) then Kaboom
generally speaking i think i am ok with variance. What i did not see or figure out because that is not what the simple example of co-variance and contravariance explain as use cases, and would like to confirm here:
The return type of a function as parameter is checked for variance position of the outer container.
Typically the example would be
Container[+A] {
def outerfunction[B](value: A): B
}
We are then explained, can't do, contra-variance position for A. I will not re-do to full explanation as to why. Let's assume we all understand it.
What is not usually explained is:
Container[+A] {
def outerfunction(f: ??? => A): A
}
It is not just taking a parameter of type A, but also taking any function parameter that return that A. The compiler goes at length to check that too. I wonder if it stops here, or if it is anything that can produce an A, as parameter to a function of the Container.
回答1:
Your understanding is completely correct. To be honest, I am not sure what exactly is the question, but I will assume it's - which places does compiler check in a case such as:
trait Container[+A] {
def outerfunction(f: String => A): A
}
And the answer is - all of them.
So when compiler sees trait Container[+A]
, it will check the body of that Container
for all occurrences of A
, to see if they are in:
- parameter position (which brings the contravariant requirement)
- return type position (covariant requirement)
- both (invariant requirement)
- neither (so-called phantom variance).
In case of Container[+A]
, it will require that all occurrences of A
are in covariant position, meaning that it will have a problem with String => A
.
It's as simple as that. Doesn't matter if it's an "inner function" or an "outer function".
来源:https://stackoverflow.com/questions/64969602/clarifying-contravariance-nature-of-the-return-type-of-a-function-as-parameter-a