Typ-Schlussfolgerung

Typ-Schlussfolgerung bezieht sich auf den automatischen Abzug des Typs eines Ausdrucks auf einer Programmiersprache. Wenn einige, aber nicht alle, Typ-Anmerkungen bereits anwesend sind, wird es Typ-Rekonstruktion genannt.

Es ist eine Eigenschaft-Gegenwart auf einigen stark statisch getippten Sprachen. Es ist häufig für — aber nicht beschränkt auf — funktionelle Programmiersprachen im Allgemeinen charakteristisch. Einige Sprachen, die Typ-Schlussfolgerung einschließen, sind ML, OCaml, Haskell, Scala, D, Sauber, Opa und Go. Es ist kürzlich (einigermaßen) zum Visuellen Grundlegend hinzugefügt worden (mit der Version 9.0 anfangend), C# (mit der Version 3.0 anfangend), und C ++ 11. Es wird auch für Perl 6 geplant. Die Fähigkeit, Typen abzuleiten, macht automatisch viele Programmieraufgaben leichter, den Programmierer frei verlassend, Typ-Anmerkungen wegzulassen, während sie noch Datentypprüfung erlaubt.

Nicht technische Erklärung

Auf den meisten Programmiersprachen ließen alle Werte einen Typ ausführlich während der Übersetzung erklären, die Werte beschränkend, die ein besonderer Ausdruck an der Durchlaufzeit übernehmen kann. Zunehmend gerade rechtzeitig macht Kompilation die Unterscheidung zwischen Durchlaufzeit und strittiger Übersetzungszeit. Jedoch, historisch, wenn der Typ eines Werts nur an der Durchlaufzeit bekannt ist; diese Sprachen werden dynamisch getippt. Auf anderen Sprachen ist der Typ eines Ausdrucks nur während der Übersetzung bekannt; diese Sprachen werden statisch getippt. Auf statisch getippten Sprachen müssen der Eingang und die Output-Arten von Funktionen und lokalen Variablen normalerweise durch Typ-Anmerkungen ausführlich zur Verfügung gestellt werden. Zum Beispiel, in C:

interne Nummer addone (interne Nummer x) {\

int Ergebnis;/*declare-Ergebnis der ganzen Zahl (c Sprache) * /

resultieren Sie = x+1;

geben Sie Ergebnis zurück;

}\</Quelle>

Die Unterschrift dieser Funktionsdefinition erklärt, dass das eine Funktion ist, die ein Argument, eine ganze Zahl nimmt, und eine ganze Zahl zurückgibt. erklärt, dass die lokale Variable eine ganze Zahl ist. In einer hypothetischen Sprachunterstützen-Typ-Schlussfolgerung könnte der Code wie das stattdessen geschrieben werden:

Val-Ergebnis; resultieren Sie/*inferred-type * /

val result2; resultieren Sie/*inferred-type #2 * /

resultieren Sie = x+1;

result2 = x+1.0;/* diese Linie wird (auf der vorgeschlagenen Sprache) * / nicht arbeiten

geben Sie Ergebnis zurück;

} </Quelle>

Das sieht sehr ähnlich dem aus, wie Code auf einer dynamisch getippten Sprache geschrieben wird, aber mit einigen Extraeinschränkungen (beschrieben unten) würde es möglich sein, die Typen aller Variablen während der Übersetzung abzuleiten. Im Beispiel oben würde der Bearbeiter ableiten, dass und ganze Typ-Zahl haben und eine Funktion ist. Die Variable wird auf eine gesetzliche Weise nicht verwendet, so würde sie keinen Typ haben.

Auf der imaginären Sprache, auf der das letzte Beispiel geschrieben wird, würde der Bearbeiter annehmen, dass, ohne Information zum Gegenteil, zwei ganze Zahlen nimmt und eine ganze Zahl zurückgibt. (Das ist, wie es in, zum Beispiel, OCaml arbeitet). Davon kann der Typ inferencer ableiten, dass der Typ dessen eine ganze Zahl ist, was bedeutet, ist eine ganze Zahl, und so ist der Rückwert dessen eine ganze Zahl. Ähnlich seitdem verlangt, dass beide seiner Argumente desselben Typs sind, eine ganze Zahl sein müssen, und deshalb eine ganze Zahl als ein Argument akzeptieren.

Jedoch, in der nachfolgenden Linie, wird result2 durch das Hinzufügen einer Dezimalzahl "" mit der Fließkommaarithmetik, das Verursachen eines Konflikts im Gebrauch sowohl für die ganze Zahl als auch für Schwimmpunkt-Ausdrücke berechnet. Der richtige Algorithmus der Typ-Schlussfolgerung für solch eine Situation ist seit 1958 bekannt gewesen und ist bekannt gewesen, seit 1982 richtig zu sein. Es besucht die vorherigen Schlussfolgerungen wieder und verwertet den allgemeinsten Typ vom Anfang: in diesem Fall Schwimmpunkt. Oft, jedoch, werden degenerierte Algorithmen der Typ-Schlussfolgerung verwendet, die des Zurückverfolgens unfähig sind und stattdessen eine Fehlermeldung in solch einer Situation erzeugen. Ein Algorithmus der Zwischenallgemeinheit erklärt implizit result2 als eine Schwimmpunkt-Variable, und die Hinzufügung wandelt sich implizit zu einem Schwimmpunkt um. Das kann richtig sein, wenn die Benennen-Zusammenhänge nie ein Schwimmpunkt-Argument liefern. Solch eine Situation zeigt den Unterschied zwischen der Typ-Schlussfolgerung, die Typ-Konvertierung und implizite Typ-Konvertierung nicht einschließt, die Daten zu einem verschiedenen Datentyp häufig ohne Beschränkungen zwingt.

Das neue Erscheinen gerade rechtzeitig der Kompilation berücksichtigt hybride Annäherungen, wo der Typ von durch den verschiedenen rufenden Zusammenhang gelieferten Argumenten während der Übersetzung bekannt ist, und eine Vielzahl von kompilierten Versionen derselben Funktion erzeugen kann. Jede kompilierte Version kann dann für einen verschiedenen Satz von Typen optimiert werden. Zum Beispiel erlaubt JIT Kompilation dort, mindestens zwei kompilierte Versionen von addone zu sein:

:A-Version, die einen Eingang der ganzen Zahl akzeptiert und implizite Typ-Konvertierung verwendet.

:A-Version, die eine Schwimmpunkt-Zahl, wie eingegeben, akzeptiert und Schwimmpunkt-Instruktionen überall verwertet.

Technische Beschreibung

Typ-Schlussfolgerung ist die Fähigkeit automatisch abzuleiten, entweder teilweise oder völlig, der Typ eines Ausdrucks während der Übersetzung. Der Bearbeiter ist häufig im Stande, den Typ einer Variable oder die Typ-Unterschrift einer Funktion ohne ausführliche Typ-Anmerkungen abzuleiten, die geben worden sind. In vielen Fällen ist es möglich, Typ-Anmerkungen aus einem Programm völlig wegzulassen, wenn das Typ-Interferenzsystem, oder das Programm robust genug ist oder Sprache einfach genug ist.

Um die Information zu erhalten, die erforderlich ist, den Typ eines Ausdrucks abzuleiten, sammelt der Bearbeiter entweder diese Information als die gesamte und nachfolgende Verminderung der Typ-Anmerkungen, die für seine Subausdrücke, oder durch ein implizites Verstehen des Typs von verschiedenen Atomwerten gegeben sind (z.B wahr: Bool; 42: Ganze Zahl; 3.14159: Echt; usw.). Es ist durch die Anerkennung der schließlichen Verminderung von Ausdrücken zu implizit getippten Atomwerten, dass der Bearbeiter für eine Typ-Schließen-Sprache im Stande ist, ein Programm völlig ohne Typ-Anmerkungen zu kompilieren. Im Fall von komplizierten Formen der höherwertigen Programmierung und polymorphism ist es für den Bearbeiter nicht immer möglich, so viel jedoch abzuleiten, und Typ-Anmerkungen sind gelegentlich für die Begriffserklärung notwendig.

Beispiel

Lassen Sie uns zum Beispiel die Funktion von Haskell denken, die eine Funktion auf jedes Element einer Liste anwendet, und als definiert werden kann:

Karte f [] = []

Karte f (first:rest) = f zuerst: Rest der Karte f

Davon ist es offensichtlich, dass die Funktion eine Liste als sein zweites Argument nimmt, dass sein erstes Argument eine Funktion ist, die auf den Typ von Elementen dieser Liste angewandt werden kann, und dass das Ergebnis dessen als eine Liste mit Elementen gebaut wird, die Ergebnisse dessen sind.

So annehmend, dass eine Liste Elemente desselben Typs enthält, können wir eine Typ-Unterschrift zuverlässig bauen

Karte:: (-> b)->-> [b]

wo die Syntax "" eine Funktion anzeigt, die als sein Parameter nimmt und a erzeugt. "" ist zu "" gleichwertig.

Bemerken Sie, dass der abgeleitete Typ dessen parametrisch polymorph ist: Der Typ der Argumente und die Ergebnisse dessen werden nicht abgeleitet, aber als Typ-Variablen verlassen, und können so auf Funktionen und Listen von verschiedenen Typen so lange das wirkliche Typ-Match in jeder Beschwörung angewandt werden.

Typ-Interferenzalgorithmus von Hindley-Milner

Der Algorithmus hat zuerst gepflegt zu leisten Typ-Schlussfolgerung wird jetzt informell den Algorithmus von Hindley-Milner genannt, obwohl der Algorithmus Damas und Milner richtig zugeschrieben werden sollte.

Der Ursprung dieses Algorithmus ist der Typ-Interferenzalgorithmus für die einfach getippte Lambda-Rechnung, die durch den Curry von Haskell und Robert Feys 1958 ausgedacht wurde.

1969 hat J. Roger Hindley diese Arbeit erweitert und hat bewiesen, dass ihr Algorithmus immer den allgemeinsten Typ abgeleitet hat.

1978 hat Robin Milner, unabhängig von der Arbeit von Hindley, einen gleichwertigen Algorithmus, Algorithmus W zur Verfügung gestellt.

1982 hat Luis Damas schließlich bewiesen, dass der Algorithmus von Milner abgeschlossen ist und es erweitert hat, um Systeme mit polymorphen Verweisungen zu unterstützen.

Links


Puerto Galera / Richard Kempenfelt
Impressum & Datenschutz