Klärung der Kontravarianz des Rückgabetyps einer Funktion als Parameter einer Funktion eines äußeren konvarianten Containers
In Option haben wir
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 Entweder haben wir:
def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B]
Ich verstehe, was los ist und warum, ein ziemlich erweitertes Beispiel könnte dies sein
OrElse ({Option [B]}). Map {....} Wenn B so ist, dass A:> B, dann erhalten Sie bei Some (a) Some (a) .map (f: B => ??? ) dann Kaboom
Im Allgemeinen denke ich, dass ich mit Varianz einverstanden bin. Was ich nicht gesehen oder herausgefunden habe, weil dies nicht das ist, was das einfache Beispiel von Co-Varianz und Kontravarianz als Anwendungsfälle erklärt, und das ich hier bestätigen möchte:
Der Rückgabetyp einer Funktion als Parameter wird auf die Varianzposition des Außencontainers überprüft.
Typischerweise wäre das Beispiel
Container[+A] {
def outerfunction[B](value: A): B
}
Wir werden dann erklärt, können nicht, Gegen-Varianz-Position für A. Ich werde nicht zur vollständigen Erklärung zurückkehren, warum. Nehmen wir an, wir alle verstehen es.
Was normalerweise nicht erklärt wird, ist:
Container[+A] {
def outerfunction(f: ??? => A): A
}
Es wird nicht nur ein Parameter vom Typ A verwendet, sondern auch ein Funktionsparameter, der diesen A zurückgibt. Der Compiler prüft dies ebenfalls ausführlich. Ich frage mich, ob es hier aufhört oder ob irgendetwas ein A als Parameter für eine Funktion des Containers erzeugen kann.
Antworten
Ihr Verständnis ist völlig richtig. Um ehrlich zu sein, bin ich mir nicht sicher, was genau die Frage ist, aber ich gehe davon aus, welche Stellen der Compiler in einem Fall wie dem folgenden überprüft:
trait Container[+A] {
def outerfunction(f: String => A): A
}
Und die Antwort ist - alle.
Wenn der Compiler sieht trait Container[+A]
, überprüft er den Hauptteil davon Container
auf alle Vorkommen von A
, um festzustellen, ob sie sich in:
- Parameterposition (die die Kontravariantenanforderung bringt)
- Rückgabetypposition (kovariante Anforderung)
- beides (unveränderliche Anforderung)
- auch nicht (sogenannte Phantomvarianz ).
In diesem Fall Container[+A]
müssen alle Vorkommen von A
in kovarianter Position sein, was bedeutet, dass es ein Problem mit hat String => A
.
So einfach ist das. Es spielt keine Rolle, ob es sich um eine "innere Funktion" oder eine "äußere Funktion" handelt.