2012-05-15 19 views
23

Ich glaube, man kann Kovarianz definieren (zumindest für Objekte) als "die Fähigkeit, einen Wert eines schmaleren (Sub-) Typs anstelle eines Wertes von einem breiteren (Super-) Typ" zu verwenden, und dass die Kontravarianz genau ist Gegenteil davon.Warum erlaubt die Funktion [-A1, ..., + B] keine Supertypen als Parameter?

Offenbar sind Scala-Funktionen Instanzen der Funktion [-A1, ..., + B] für kontravariante Parameter A1, usw. und kovarianter Rückgabetyp B. Dies ist jedoch praktisch, um Funktionen zu unterteilen die obige Definition bedeutet, dass ich irgendwelche Supertypen als Parameter übergeben kann?

Bitte beraten, wo ich mich irre.

Antwort

56

Kovarianz und Kontra sind Qualitäten von die Klasse nicht Qualitäten die Parameter. (Sie sind Qualitäten, die von den Parametern abhängen, aber sie machen Aussagen über die Klasse.)

So Function1[-A,+B] bedeutet, dass eine Funktion, die übergeordneten Klassen von A nimmt als eine Unterklasse von die ursprüngliche Funktion betrachtet werden.

ist dies in der Praxis Lassen Sie sehen:

class A 
class B extends A 
val printB: B => Unit = { b => println("Blah blah") } 
val printA: A => Unit = { a => println("Blah blah blah") } 

Angenommen, Sie eine Funktion benötigen, die weiß, wie ein B drucken:

def needsB(f: B => Unit, b: B) = f(b) 

Sie in printB passieren könnte. Aber Sie könnten auch übergeben in printA, da es auch weiß, wie B s (und mehr!) Zu drucken, als ob A => Unit eine Unterklasse von B => Unit wäre. Genau das bedeutet Kontravarianz. Es bedeutet nicht, dass Sie Option[Double] in printB übergeben und alles außer einem Kompilierungsfehler erhalten können!

(Kovarianz ist der andere Fall. M[B] <: M[A] wenn B <: A)

+0

Danke, das war sehr klar. Versuch, (neu) zu definieren: "Co/Kontra-Varianz sind Eigenschaften, die die Subtyprelation zwischen Typen vorgeben, abhängig von der Art derselben Beziehung zwischen ihren Komponententypen". Abstrakt, ich weiß, aber ich bevorzuge eine Definition ohne Beispiele (obwohl Ihre sehr hilfreich war). – bjt38

+0

danke für die -A, könntest du erklären warum ist + B in der Funktion1 [-A, + B] – liango

+0

@liango - Eine Erklärung mit einem Beispiel: Wenn du eine 'String' zurückgibst, gibst du sicher ein' Object' zurück, also '. .. => String' muss eine Unterklasse von '... => Object' sein. Das bedeutet "+ B". –

4

Hier sind zwei verschiedene Ideen am arbeiten. Man verwendet Subtyping, um spezifischere Argumente an eine Funktion übergeben zu lassen (Subsumption). Die andere Möglichkeit besteht darin, die Subtypisierung von Funktionen selbst zu überprüfen.

Für die Überprüfung der Argumente einer Funktion müssen Sie nur überprüfen, ob die angegebenen Argumente Untertypen der deklarierten Argumenttypen sind. Das Ergebnis muss auch ein Subtyp des deklarierten Typs sein. Hier überprüfen Sie tatsächlich das Subtyping.

Die contra/Co-Varianz des Ergebnisses & Parameter nur in Faktor, wenn Sie, ob ein Funktionstyp gegeben überprüfen möchten ein Subtyp eines anderen Funktionstyp ist. Wenn also ein Parameter den Typ Function[A1, ... ,B] hat, muss das Argument ein Funktionstyp Function[C1, ..., D] sein, wobei A1 <: C1 ... und D <: B.

Diese Argumentation ist nicht spezifisch für Scala und gilt für andere statisch typisierte Sprachen mit Subtyping.

-1

Covariant Mittel aus breitem (Super) zu schmaleren (sub) umwandelt.Zum Beispiel haben wir zwei Klassen: eine ist Tier (super) und die andere ist Katze dann mit Kovariante, können wir Tier in Katze umwandeln.

Kontra-Variante ist genau das Gegenteil von Kovariant, was Katze zu Tier bedeutet.

Invariant bedeutet, dass es nicht konvertiert werden kann.

18

Diese Frage ist alt, aber ich denke, eine klarere Erklärung ist, das Liskow-Substitutionsprinzip aufzurufen: Alles, was an einer Oberklasse wahr ist, sollte für alle Unterklassen gelten. Du solltest in der Lage sein, mit einem SubFoo alles zu tun, was du mit einem Foo machen kannst, und vielleicht mehr.

Angenommen, wir haben Calico <: Katze <: Tier, und Husky <: Hund <: Tier. Lassen Sie uns einen Function[Cat, Dog] ansehen. Welche Aussagen treffen darauf zu? Es gibt zwei:

(1) Sie in jeder Katze passieren kann (so dass jede Unterklasse von Cat)

(2) Sie können auf dem Rückgabewert jeder Hund Methode aufrufen

So macht Function[Calico, Dog] <: Function[Cat, Dog] Sinn ? Nein, Aussagen, die für die Oberklasse gelten, gelten nicht für die Unterklasse, nämlich Anweisung (1). Du kannst keine Katze an eine Funktion weitergeben, die nur Kaliko-Katzen aufnimmt.

Aber macht Sinn? Ja, alle Aussagen zur Oberklasse gelten für die Unterklasse. Ich kann immer noch eine Katze reinlassen - in der Tat kann ich noch mehr als das, ich kann jedes Tier übergeben - und ich kann alle Dog-Methoden auf den zurückgegebenen Wert aufrufen.

So A <: B impliziert Function[B, _] <: Function[A, _]

Nun tut Function[Cat, Husky] <: Function[Cat, Dog] Sinn? Ja, alle Aussagen über die Oberklasse gelten für die Unterklasse; Ich kann immer noch eine Katze einreichen, und ich kann immer noch alle Dog-Methoden auf den zurückgegebenen Wert aufrufen - in der Tat kann ich noch mehr als das tun, ich kann alle Husky-Methoden auf den zurückgegebenen Wert aufrufen.

Aber macht Function[Cat, Animal] <: Function[Cat, Dog] Sinn? Nein, Aussagen, die für die Oberklasse wahr sind, gelten nicht für die Unterklasse, nämlich die Aussage (2). Ich kann nicht alle auf Dog verfügbaren Methoden auf dem zurückgegebenen Wert aufrufen, nur die auf Animal verfügbaren.

Also mit einem Function[Animal, Husky] kann ich alles tun, was ich mit einem Function[Cat, Dog] tun kann: Ich kann in jedem Cat übergeben, und ich kann alle Dog-Methoden auf den zurückgegebenen Wert aufrufen. Und ich kann noch mehr tun: Ich kann andere Tiere weitergeben, und ich kann die auf Husky verfügbaren Methoden aufrufen, die bei Dog nicht verfügbar sind. Also macht es Sinn: Function[Animal, Husky] <: Function[Cat, Dog]. Der erste Typparameter kann durch eine Superklasse ersetzt werden, der zweite durch eine Subklasse.

+0

Wie kann ich <: programmgesteuert mit den Beispielen überprüfen, die Sie angegeben haben? –

Verwandte Themen