www.wikidata.de-de.nina.az
Hindley Milner HM ist ein Verfahren der Typinferenz mit parametrischem Polymorphismus fur den Lambda Kalkul Es wurde erstmals von J Roger Hindley 1 beschrieben und spater von Robin Milner 2 wiederentdeckt Luis Damas trug eine genaue formale Analyse und einen Beweis der Methode in seiner Doktorarbeit 3 bei weshalb das Verfahren auch als Damas Milner 4 bezeichnet wird Unter den herausragenden Eigenschaften des HM sind Vollstandigkeit und die Fahigkeit den allgemeinsten Typ einer gegebenen Quelle ohne Hinzunahme von Annotationen oder sonstigen Hinweisen bestimmen zu konnen HM ist ein effizientes Verfahren das die Typisierung nahezu in linearer Zeit bzgl der Grosse der Quelle ermitteln kann womit es praktisch zum Typisieren grosser Programme anwendbar ist HM wird bevorzugt in funktionalen Sprachen wie OCaml Reason eingesetzt Es wurde erstmals als Teil des Typsystems der Programmiersprache ML implementiert Seitdem wurde HM auf verschiedene Weise erweitert insbesondere durch beschrankte Typen wie sie in Haskell verwendet werden Inhaltsverzeichnis 1 Einleitung 2 Die Syntax 2 1 Freie Typvariablen 2 2 Kontext und Typung 2 3 Anmerkungen zur Ausdrucksstarke 3 Ordnung polymorpher Typen 4 Die Deduktionsmaschinerie 5 Die Typungsregeln 5 1 Haupttyp 5 2 Let Polymorphismus 6 Ubergang zum Algorithmus 6 1 Freiheitsgrade bei der Regelauswahl 6 2 Syntaxgesteuertes Regelsystem 6 3 Freiheitsgrade bei der Regelinstanzierung 7 Algorithmus W 7 1 Der Algorithmus W im Original 8 Weitere Themen 8 1 Rekursive Definitionen 9 Anmerkungen 10 EinzelnachweiseEinleitung BearbeitenDamas und Milner 4 trennen in der Gliederung ihrer Original Veroffentlichung zwei sehr verschiedene Aufgaben wobei die erste darin besteht zu beschreiben welche Typen ein Ausdruck haben kann Die andere ist einen Algorithmus anzugeben der tatsachlich einen Typ ermittelt Beide Aspekte getrennt voneinander zu betrachten erlaubt sich eigens auf die Logik d h Bedeutung hinter dem Algorithmus konzentrieren und zugleich einen Prufstein fur die Eigenschaften des Verfahrens festlegen zu konnen Wie Ausdrucke und Typen zueinander passen wird mit Hilfe eines Deduktionssystems beschrieben Wie jedes Beweissystem erlaubt es auf verschiedenen Wegen zu einem Schluss zu gelangen Da ein und derselbe Ausdruck begrundbar verschiedene Typen haben kann kann das Deduktionssystem auch zu durchaus unterschiedlichen Schlussen uber einen Ausdruck kommen Im Gegensatz dazu ist bei der Typinferenz Methode selbst Algorithmus W jeder Ausfuhrungsschritt eindeutig bestimmt Naturlich konnen in der Konstruktion des Algorithmus Entscheidungen getroffen worden sein die so nicht in der Logik vorkommen und eine genauere Betrachtung und Begrundung verlangen die ohne die obige Differenzierung nicht sichtbar wurde Die Syntax BearbeitenAusdruckee x Variable e e Anwendung l x e Abstraktion l e t x e i n e displaystyle begin array lrll e amp amp x amp textrm Variable amp vert amp e e amp textrm Anwendung amp vert amp lambda x e amp textrm Abstraktion amp vert amp mathtt let x e mathtt in e end array nbsp Typenmono t a Variable D t t Anwendung poly s t a s Quantor displaystyle begin array llrll textrm mono amp tau amp amp alpha amp textrm Variable amp amp vert amp D tau dots tau amp textrm Anwendung textrm poly amp sigma amp amp tau amp amp vert amp forall alpha sigma amp textrm Quantor end array nbsp Logik und Algorithmus teilen sich die Begriffe Ausdruck und Typ deren Form durch die Syntax prazisiert wird Die zu typisierenden Ausdrucke sind die des Lambda Kalkuls erweitert um einen let Ausdruck Die Form e e displaystyle e e nbsp stellt die auch oft als e e displaystyle e e nbsp geschriebene Funktionsanwendung dar wahrend die Abstraktion l x e displaystyle lambda x e nbsp die anonyme Funktion bzw das Funktionsliteral meint die inzwischen in vielen zeitgenossischen Programmiersprachen verfugbar ist dort vielleicht nur wortreicher etwa als f u n c t i o n x r e t u r n e e n d displaystyle mathtt function x mathtt return e mathtt end nbsp ausgeschrieben Das Gesamt der Typen Sorten teilt sich in zwei Gruppen die Mono und Polytypen genannt werden note 1 Monotypen t displaystyle tau nbsp syntaktisch Terme bezeichnen immer bestimmte Typen in dem Sinne dass sie gleich nur sich selbst und verschieden von allen anderen sind Charakteristische Vertreter der Monotypen sind Typkonstanten wie i n t displaystyle int nbsp oder s t r i n g displaystyle string nbsp Typen konnen parametrisch sein wie z B M a p S e t s t r i n g i n t displaystyle Map Set string int nbsp All diese Typen sind Beispiele von Anwendungen von Typfunktionen D displaystyle D nbsp z B i n t 0 s t r i n g 0 M a p 2 S e t 1 D displaystyle left int 0 string 0 Map 2 Set 1 right subset D nbsp in den vorangegangenen Beispielen wobei die hochgestellte Ziffer die Zahl der Typparameter angibt Wahrend die Wahl von D displaystyle D nbsp grundsatzlich beliebig ist muss sie im Zusammenhang des HM wenigstens den bequemerweise infix geschriebenen Funktionstyp 2 displaystyle rightarrow 2 nbsp enthalten Beispielsweise hat eine Funktion die ganze Zahlen auf Zeichenketten abbildet den Typ i n t s t r i n g displaystyle int rightarrow string nbsp note 2 Vielleicht etwas irritierenderweise sind Typvariablen ebenfalls Monotypen Eine allein stehende Typvariable a displaystyle alpha nbsp bezeichnet einen Typ der genau so konkret ist wie etwa i n t displaystyle int nbsp oder b displaystyle beta nbsp und von beiden verschieden ist Eine als Monotyp auftretende Typvariable verhalt sich gerade so als ware sie eine Typkonstante uber die man nur eben keine weiteren Informationen besitzt Entsprechend bildet eine Funktion mit dem Typ a a displaystyle alpha rightarrow alpha nbsp nur Werte des Typs a displaystyle alpha nbsp auf sich selbst ab und kann nur auf Werte dieses Typs angewendet werden und auf keine anderen sonst Im Gegensatz dazu kann eine Funktion mit dem Polytyp a a a displaystyle forall alpha alpha rightarrow alpha nbsp jeden Wert auf einen Wert gleichen Typs abbilden Die identische Funktion ist ein Wert fur diesen Typ Als weiteres Beispiel ist a S e t a i n t displaystyle forall alpha Set alpha rightarrow int nbsp der Typ einer Funktion die beliebige endliche Menge auf ganze Zahlen abbildet Die Zahl der Elemente der Menge ist ein Wert fur diesen Typ Quantoren durfen allerdings nur auf oberster Ebene auftreten d h der Typ a a a a displaystyle forall alpha alpha rightarrow forall alpha alpha nbsp beispielsweise ist durch die Syntax ausgeschlossen Ferner sind Monotypen eine Teilmenge der Polytypen so dass Typen insgesamt die allgemeine Form a 1 a n t displaystyle forall alpha 1 dots forall alpha n tau nbsp haben Freie Typvariablen Bearbeiten Freie Typvariablenfrei a a frei D t 1 t n i 1 n frei t i frei a s frei s a displaystyle begin array ll text frei alpha amp left alpha right text frei D tau 1 dots tau n amp bigcup limits i 1 n text frei tau i text frei forall alpha sigma amp text frei sigma left alpha right end array nbsp In einem Typ a 1 a n t displaystyle forall alpha 1 dots forall alpha n tau nbsp ist das Symbol displaystyle forall nbsp der die Typvariablen a i displaystyle alpha i nbsp im Monotyp t displaystyle tau nbsp bindende Quantor Die Variablen a i displaystyle alpha i nbsp heissen quantifiziert Jedes Auftreten einer quantifizierten Variablen in t displaystyle tau nbsp heisst gebunden und alle ungebundenen Typvariablen heissen frei Wie im Lambda Kalkul ist der Begriff der freien und gebundenen Variablen grundlegend fur das Verstandnis der Bedeutung der Typen Dies ist sicherlich der schwierigste Teil des HM vielleicht weil Polytypen die freie Typvariablen enthalten nicht in Programmiersprachen wie Haskell ausgedruckt werden konnen Genauso gibt es keine freien Variablen in Prolog Klauseln Insbesondere mit beiden Sprachen erfahrene Entwickler die somit eigentlich alle Voraussetzungen fur den HM kennen konnen diesen Punkt leicht ubersehen In Haskell beispielsweise sind alle Typvariablen implizit quantifiziert z B bedeutet der Haskell Typ a gt a displaystyle texttt a gt a nbsp hier a a a displaystyle forall alpha alpha rightarrow alpha nbsp Da Typen wie a a displaystyle alpha rightarrow alpha nbsp obwohl sie durchaus in Haskell auftreten konnen dort nicht ausdruckbar sind konnen sie leicht mit der quantifizierten Version verwechselt werden Welche Funktionen konnen nun einen Typ wie z B b b a displaystyle forall beta beta rightarrow alpha nbsp d h eine Mischung von gebundenen und ungebundenen Typvariablen enthalten und was bedeutet eine freie Typvariable darin Beispiel 1let b a r a b a b a l x let f o o b b a l y x in f o o in b a r displaystyle begin array l textbf let bar forall alpha forall beta alpha rightarrow beta rightarrow alpha lambda x quad textbf let foo forall beta beta rightarrow alpha lambda y x quad textbf in foo textbf in bar end array nbsp In Beispiel 1 ist der let Ausdruck f o o displaystyle foo nbsp mit Typ Annotationen in eckigen Klammern versehen Offensichtlich wird der Parameter y displaystyle y nbsp im Korper nicht verwendet wohl aber die im ausseren Kontext von f o o displaystyle foo nbsp gebundene Variable x displaystyle x nbsp Als Konsequenz akzeptiert f o o displaystyle foo nbsp jeden Wert als Argument wahrend sie einen Wert liefert der ausserhalb gebunden ist und mithin auch sein Typ Im Gegensatz dazu hat b a r displaystyle bar nbsp den Typ a b a b a displaystyle forall alpha forall beta alpha rightarrow beta rightarrow alpha nbsp in dem alle Typvariablen gebunden auftreten Wertet man z B b a r 1 displaystyle bar 1 nbsp aus erhalt man als Ergebnis eine Funktion vom Typ b b i n t displaystyle forall beta beta rightarrow int nbsp was perfekt wiedergibt dass der Monotyp a displaystyle alpha nbsp von f o o displaystyle foo nbsp in b b a displaystyle forall beta beta rightarrow alpha nbsp durch den Aufruf verfeinert wurde In diesem Beispiel wird die freie Monotypvariable a displaystyle alpha nbsp im Typ von f o o displaystyle foo nbsp durch die Quantifikation im ausseren Geltungsbereich mit Bedeutung beladen namlich im Typ von b a r displaystyle bar nbsp Dies heisst im Zusammenhang dieses Beispiels dass dieselbe Typvariable a displaystyle alpha nbsp sowohl gebunden als auch frei in verschiedenen Typen auftritt Insofern kann eine freie Typvariable ohne Kenntnis des Kontexts nicht besser interpretiert werden als zu konstatieren dass es sich um einen Monotyp handelt Anders gesagt ist eine Typung im Allgemeinen ohne Kenntnis des Kontexts nicht aussagekraftig Kontext und Typung Bearbeiten SyntaxKontext G ϵ l e e r G x s Typung G e s displaystyle begin array llrl text Kontext amp Gamma amp amp epsilon mathtt leer amp amp vert amp Gamma x sigma text Typung amp amp amp Gamma vdash e sigma end array nbsp Freie Typvariablenfrei G x s G frei s displaystyle begin array ll text frei Gamma amp bigcup limits x sigma in Gamma text frei sigma end array nbsp Um die bislang getrennten Teile der Syntax Ausdrucke und Typen sinnvoll zusammenzubringen wird also ein Drittes der Kontext benotigt Syntaktisch ist dieser einer Liste von Paaren x s displaystyle x sigma nbsp Belegung s a Belegung Zuordnung Zuweisung genannt die jeder Wertvariablen x i displaystyle x i nbsp im Kontext einen Typ s i displaystyle sigma i nbsp zuordnet Alle drei Teile zusammen ergeben eine Typung der Form G e s displaystyle Gamma vdash e sigma nbsp die aussagt dass unter der Annahme G displaystyle Gamma nbsp der Ausdruck e displaystyle e nbsp den Typ s displaystyle sigma nbsp hat Da nun die vollstandige Syntax zur Verfugung steht kann schliesslich eine sinnvolle Aussage uber den Typ von f o o displaystyle foo nbsp in Beispiel 1 gemacht werden namlich x a l y x b b a displaystyle x alpha vdash lambda y x forall beta beta rightarrow alpha nbsp Im Gegensatz zu den vorangehenden Formulierungen ist die Monotypvariable a displaystyle alpha nbsp nicht langer frei d h bedeutungslos sondern im Kontext als Typ der Wertvariablen x displaystyle x nbsp gebunden Offenbar spielt der Umstand ob eine Typvariable im Kontext frei oder gebunden auftritt eine bedeutsame Rolle fur einen Typ im Rahmen einer Typung daher wird f r e i G displaystyle mathrm frei Gamma nbsp im Kasten prazisiert Anmerkungen zur Ausdrucksstarke Bearbeiten Da die Syntax des Ausdrucks einem mit dem Lambda Kalkul unvertrauten Leser bei weitem zu ausdrucksschwach erscheinen mag und da die Beispiele dieses Vorurteil eher stutzen werden ist vielleicht der Hinweis hilfreich dass sich HM nicht auf Spielzeugsprachen bezieht Ein wesentliches Ergebnis der Forschung im Bereich der Berechenbarkeit ist dass obige Ausdruckssyntax ohne die let Klausel stark genug ist jede berechenbare Funktion zu beschreiben Daruber hinaus konnen alle weiteren Konstruktionen in Programmiersprachen relativ direkt syntaktisch in Ausdrucke des Lambda Kalkuls uberfuhrt werden Darum werden diese einfachen Ausdrucke als Modell fur Programmiersprachen verwendet Ein Verfahren das gut auf das Lambda Kalkul anwendbar ist kann leicht auf alle oder wenigstens viele andere syntaktische Konstruktionen einer speziellen Programmiersprache mittels der eben erwahnten Transformationen ubertragen werden Zum Beispiel kann die zusatzliche Ausdrucksvariante let x e 1 in e 2 displaystyle textbf let x e 1 textbf in e 2 nbsp transformiert werden nach l x e 2 e 1 displaystyle lambda x e 2 e 1 nbsp Sie ist der Ausdruckssyntax im HM nur zur Unterstutzung der Generalisierung wahrend der Typinferenz hinzugefugt worden und nicht weil es der Syntax an Berechnungsstarke fehlt HM behandelt also die Inferenz von Typen in Programmen im Allgemeinen und die verschieden funktionalen Sprachen die diese Methode verwenden belegen wie gut ein Ergebnis das nur fur die Syntax des Lambda Kalkuls formuliert ist auf syntaktisch komplexe Sprachen erweitert werden kann Im Gegensatz zum Eindruck dass die Ausdrucke zu ausdrucksschwach fur praktische Anwendungen seien sind sie tatsachlich zu ausdrucksstark um im Allgemeinen uberhaupt typisiert zu werden Dies ist eine Konsequenz der Unentscheidbarkeit fur inhaltliche Aussagen uber Ausdrucke des Lambda Kalkuls Entsprechend ist die Berechnung der Typung von Programmen i Allg ein hoffnungsloses Unterfangen Abhangig von der Natur des Typsystems wird dieses u U entweder nicht terminieren oder anderweitig den Dienst verweigern HM gehort zur letzteren Gruppe von Typsystemen Ein Kollaps des Sortenapparats erscheint hier als eher subtile Situation in der nur noch ein und derselbe Typ fur die interessierenden Ausdrucke ermittelt wird Dies ist kein Fehler im HM sondern ein dem Problem der Typisierung selbst innewohnende Eigenschaft die leicht in jeder stark getypten Sprache erzeugt werden kann Hierzu kodiert man einen Auswerter d h die universelle Funktion fur die zu einfachen Ausdrucke Man erhalt damit einen einzelnen konkreten Typ der den universellen Datentyp reprasentiert wie er in typlosen Sprachen auftritt Der Sortenapparat der Gastsprache ist dann kollabiert und kann die verschiedenen Typen von Werten nicht mehr unterscheiden die der Auswertung ubergeben oder von dieser erhalten werden In diesem Zusammenhang ermittelt oder uberpruft der Sortenapparat immer noch Typen aber immer denselben gerade als ware das Typsystem gar nicht mehr vorhanden Ordnung polymorpher Typen BearbeitenWahrend die Gleichheit von Monotypen rein syntaktisch ist haben Polytypen eine reichere Beziehung zu anderen Sorten die durch eine Spezialisierungsrelation displaystyle sqsubseteq nbsp ausgedruckt wird wobei s s displaystyle sigma sqsubseteq sigma nbsp bedeutet dass s displaystyle sigma nbsp spezieller ist als s displaystyle sigma nbsp Wird eine polymorphe Funktion auf einen Wert angewendet dann muss sie ihre Form an den speziellen Typ dieses Wertes anpassen Wahrend dieser Anpassung andert sie mithin auch ihren Typ um zu dem des Parameters zu passen Wird beispielsweise die identische Funktion mit dem Typ a a a displaystyle forall alpha alpha rightarrow alpha nbsp auf eine Zahl mit dem Typ i n t displaystyle int nbsp angewendet dann konnen diese zunachst nicht zusammenwirken da alle Typen verschieden sind und nicht passen Was in dieser Lage benotigt wird ist eine Funktion vom Typ i n t i n t displaystyle int rightarrow int nbsp Hierzu wird die polymorphe Identitat im Rahmen der Anwendung in eine monomorphe Version ihrer selbst verwandelt In Begriffen der Spezialisierung ausgedruckt kann man dies als a a a i n t i n t displaystyle forall alpha alpha rightarrow alpha sqsubseteq int rightarrow int nbsp schreiben Nun ist die Formwandlung polymorpher Werte nicht vollig beliebig sondern vielmehr durch den ursprunglichen Polytyp begrenzt Dem Vorgang in diesem Beispiel folgend kann man die Spezialisierungsregel so umschreiben dass ein polymorpher Typ a t displaystyle forall alpha tau nbsp durch konsistente Ersetzung jedes Auftretens von a displaystyle alpha nbsp in t displaystyle tau nbsp spezialisiert wird wonach die Quantifizierung entfallt Wahrend diese Regel gut fur alle Monotypen als Einsetzung funktioniert schlagt sie fehl wenn ein Polytyp als Ersetzung auftritt Versucht man dies z B mit b b displaystyle forall beta beta nbsp dann erhalt man einen unsyntaktischen Typ b b b b displaystyle forall beta beta rightarrow forall beta beta nbsp Aber nicht nur das Selbst wenn eine geschachtelte Quantifizierung in der Syntax zulassig ware wurde das Ergebnis dieser Ersetzung die Eigenschaft des ursprunglichen Typs in dem Parameter und Resultat der Funktion denselben Typ haben nicht mehr erhalten da nun beide Untertypen unabhangig voneinander geworden sind und jeder eine Spezialisierung mit verschiedenen Typen erlauben wurde so z B s t r i n g S e t i n t displaystyle string rightarrow Set int nbsp was kaum die richtige Aufgabe fur eine identische Funktion ware Die syntaktische Einschrankung der Quantifizierung auf die oberste Ebene verhindert diese unerwunschte Generalisierung wahrend der Spezialisierung Anstelle von b b b b displaystyle forall beta beta rightarrow forall beta beta nbsp muss in diesem Fall der speziellere Typ b b b displaystyle forall beta beta rightarrow beta nbsp verwendet werden Man kann die eben erfolgte Spezialisierung durch eine weitere mit dem Typ a a displaystyle forall alpha alpha nbsp wieder aufheben In Bezeichnungen der Relation erhalt man zusammenfassend a a a b b b a a a displaystyle forall alpha alpha rightarrow alpha sqsubseteq forall beta beta rightarrow beta sqsubseteq forall alpha alpha rightarrow alpha nbsp was bedeutet dass syntaktische verschiedene Polytypen gleich bzgl der Umbenennung ihrer quantifizierten Variablen sind Spezialisierungsregelt a i t i t b i frei a 1 a n t a 1 a n t b 1 b m t displaystyle displaystyle frac tau left alpha i tau i right tau quad beta i not in textrm frei forall alpha 1 forall alpha n tau forall alpha 1 forall alpha n tau sqsubseteq forall beta 1 forall beta m tau nbsp Konzentriert man sich nun nur auf die Frage ob ein Typ spezieller als ein anderer ist und mehr wofur ein speziellerer Typ verwendet wird dann kann man die Spezialisierung wie im nebenstehenden Kasten zusammenfassen Im Uhrzeigersinn umschrieben wird ein Typ a 1 a n t displaystyle forall alpha 1 dots forall alpha n tau nbsp spezialisiert indem man jede der quantifizierten Variablen a i displaystyle alpha i nbsp konsistent durch einen beliebigen Monotyp t i displaystyle tau i nbsp ersetzt so dass man insgesamt einen Monotyp t displaystyle tau nbsp erhalt Abschliessend konnen Typvariablen die im ursprunglichen Typ nicht frei auftraten optional quantifiziert werden Die Spezialisierungsregel tragt also Sorge dass keine freie Variable d h Monotyp im ursprunglichen Typ ungewollt durch einen Quantor gebunden wird Ursprunglich quantifizierte Variablen konnen aber beliebig konsistent ersetzt werden auch durch Typen die neue quantifizierte oder unquantifizierte Variablen einfuhren Beginnend mit dem Polytyp a a displaystyle forall alpha alpha nbsp kann eine Spezialisierung den Korper entweder durch eine andere quantisierte Variable ersetzen letztlich eine Umbenennung oder durch eine Typkonstante einschliesslich des Funktionstyps die Parameter haben kann oder nicht jede gefullt mit einem Monotyp oder einer quantifizierten Typvariablen Sobald eine quantifizierte Variable durch eine Typanwendung ersetzt worden ist kann diese nicht mehr durch eine weitere Spezialisierung wieder aufgehoben werden wie es bei der Ersetzung durch eine quantifizierte Variable moglich war Typanwendungen sind also da um zu bleiben Nur wenn diese eine weitere quantifizierte Typvariable enthalten kann die Spezialisierung durch deren weitere Ersetzung fortgefuhrt werden Die Spezialisierung fuhrt also keine weiteren Gleichheiten auf Polytypen ausser der bereits bekannten Umbenennung ein Polytypen sind bis auf die Umbenennung ihrer gebundenen Variablen syntaktisch gleich Die Gleichheit von Typen ist eine reflexive antisymmetrische und transitive Relation und die verbleibende Spezialisierung von Polytypen ist transitiv Damit ist die Relation displaystyle sqsubseteq nbsp eine Halbordnung Die Deduktionsmaschinerie BearbeitenDie Syntax der RegelnP r a d i k a t s s a f r e i G x a G Urteil Typung P r a m i s s e Urteil P r a d i k a t Schluss Urteil Regel P r a m i s s e Schluss N a m e displaystyle begin array lrl mathrm Pr ddot a dikat amp amp sigma sqsubseteq sigma amp vert amp alpha not in mathrm frei Gamma amp vert amp x alpha in Gamma text Urteil amp amp text Typung mathrm Pr ddot a misse amp amp text Urteil vert mathrm Pr ddot a dikat text Schluss amp amp text Urteil text Regel amp amp displaystyle frac mathrm Pr ddot a misse dots textrm Schluss quad mathtt Name end array nbsp Die Syntax von HM wird durch die Syntax der Inferenzregeln fortgefuhrt die den Korper des formalen Systems bilden indem sie die Typungen als Urteile verwenden Die Regeln definieren aus welchen Voraussetzungen man welche Schlusse ziehen kann Zusatzlich zu den Urteilen konnen einige weiter oben eingefuhrte Randbedingungen als Pramissen verwendet werden Ein Beweis mittels der Regeln ist eine Sequenz von Urteilen so dass alle Pramissen vor den Schlussen aufgelistet werden Siehe die folgenden Beispiele 2 3 fur ein mogliches Format der Beweise Von links nach rechts zeigt jede Zeile den Schluss den N a m e n displaystyle mathtt Namen nbsp der angewandten Regel und die Pramissen entweder durch Verweis auf eine vorangehende Zeile wenn die Pramisse ein Urteil ist oder durch explizite Angabe des Pradikats Die Typungsregeln BearbeitenDeklaratives Regelsystemx s G G x s V a r G e 0 t t G e 1 t G e 0 e 1 t A p p G x t e t G l x e t t A b s G e 0 s G x s e 1 t G l e t x e 0 i n e 1 t L e t G e s s s G e s I n s t G e s a frei G G e a s G e n displaystyle begin array cl displaystyle frac x sigma in Gamma Gamma vdash x sigma amp mathtt Var displaystyle frac Gamma vdash e 0 tau rightarrow tau quad quad Gamma vdash e 1 tau Gamma vdash e 0 e 1 tau amp mathtt App displaystyle frac Gamma x tau vdash e tau Gamma vdash lambda x e tau rightarrow tau amp mathtt Abs displaystyle frac Gamma vdash e 0 sigma quad quad Gamma x sigma vdash e 1 tau Gamma vdash mathtt let x e 0 mathtt in e 1 tau amp mathtt Let displaystyle frac Gamma vdash e sigma quad sigma sqsubseteq sigma Gamma vdash e sigma amp mathtt Inst displaystyle frac Gamma vdash e sigma quad alpha notin text frei Gamma Gamma vdash e forall alpha sigma amp mathtt Gen end array nbsp Der seitliche Kasten zeigt die Deduktionsregel des HM Typsystems Man kann sie grob in zwei Gruppen einteilen Die ersten vier Regeln V a r displaystyle mathtt Var nbsp A p p displaystyle mathtt App nbsp A b s displaystyle mathtt Abs nbsp und L e t displaystyle mathtt Let nbsp sind um die Syntax zentriert und geben je eine Regel fur jede der Ausdrucksformen an Ihre Bedeutung ist schon auf den ersten Blick recht offensichtlich da sie jeden Ausdruck aufteilen die Beweise der Teilausdrucke heranziehen und die Einzeltypen in den Pramissen zum Typ im Schluss kombinieren Die zweite Gruppe wird durch die verbleibenden Regeln I n s t displaystyle mathtt Inst nbsp and G e n displaystyle mathtt Gen nbsp gebildet die die Spezialisierung und Generalisierung von Typen behandeln Wahrend die I n s t displaystyle mathtt Inst nbsp Regel inhaltlich im Abschnitt uber die Spezialisierung bereits beschrieben wurde vervollstandigt die Regel G e n displaystyle mathtt Gen nbsp diese durch die umgekehrter Richtung Sie erlaubt eine Generalisierung d h eine Quantifizierung einer nicht im Kontext gebundenen Monotypvariablen Die Notwendigkeit fur die Einschrankung a f r e i G displaystyle alpha not in mathrm frei Gamma nbsp wurde im Abschnitt uber die freien Typvariablen eingefuhrt Die folgenden beiden Beispiele exerzieren das Regelsystem in Aktion Beispiel 2 Ein Beweis fur G i d n i n t displaystyle Gamma vdash id n int nbsp mit G i d a a a n i n t displaystyle Gamma id forall alpha alpha rightarrow alpha n int nbsp kann wie folgt geschrieben werden 1 G i d a a a V a r i d a a a G 2 G i d i n t i n t I n s t 1 a a a i n t i n t 3 G n i n t V a r n i n t G 4 G i d n i n t A p p 2 3 displaystyle begin array llll 1 amp Gamma vdash id forall alpha alpha rightarrow alpha amp mathtt Var amp id forall alpha alpha rightarrow alpha in Gamma 2 amp Gamma vdash id int rightarrow int amp mathtt Inst amp 1 forall alpha alpha rightarrow alpha sqsubseteq int rightarrow int 3 amp Gamma vdash n int amp mathtt Var amp n int in Gamma 4 amp Gamma vdash id n int amp mathtt App amp 2 3 end array nbsp Beispiel 3 Um die Generalisierung zu demonstrieren wird let i d l x x in i d a a a displaystyle vdash textbf let id lambda x x textbf in id forall alpha alpha rightarrow alpha nbsp gezeigt 1 x a x a V a r x a x a 2 l x x a a A b s 1 3 l x x a a a G e n 2 a f r e i ϵ 4 i d l a a a i d l a a a V a r i d l a a a i d l a a a 5 let i d l x x in i d a a a L e t 3 4 displaystyle begin array llll 1 amp x alpha vdash x alpha amp mathtt Var amp x alpha in left x alpha right 2 amp vdash lambda x x alpha rightarrow alpha amp mathtt Abs amp 1 3 amp vdash lambda x x forall alpha alpha rightarrow alpha amp mathtt Gen amp 2 alpha not in mathrm frei epsilon 4 amp id lambda alpha alpha rightarrow alpha vdash id lambda alpha alpha rightarrow alpha amp mathtt Var amp id lambda alpha alpha rightarrow alpha in left id lambda alpha alpha rightarrow alpha right 5 amp vdash textbf let id lambda x x textbf in id forall alpha alpha rightarrow alpha amp mathtt Let amp 3 4 end array nbsp Haupttyp Bearbeiten Wie in der Einleitung erwahnt erlauben die Regeln verschiedene Typen fur ein und denselben Ausdruck zu erschliessen Siehe Beispiel 2 Schritte 1 2 und Beispiel 3 Schritte 2 3 fur drei verschiedene Typungen desselben Ausdrucks Offenbar sind die verschiedenen Ergebnisse nicht vollig unabhangig sondern durch die Typordnung verbunden Es ist eine wesentliche Eigenschaft des Regelsystems und der Typordnung dass wenn mehr als ein Typ fur einen Ausdruck erschlossen werden kann sich unter diesen Typen modulo Gleichheit ein eindeutig bestimmter allgemeinster Typ in dem Sinne befindet dass alle anderen Spezialisierungen von ihm sind Wahrend ein Regelsystem es zulassen muss spezialisierte Typen herzuleiten sollte ein Typinfernzalgorithmus den allgemeinsten oder Haupttyp als Ergebnis liefern Let Polymorphismus Bearbeiten Nicht unmittelbar ersichtlich kodiert die Regelmenge eine Vorschrift unter welchen Umstanden ein Typ generalisiert werden darf und wann nicht Dies geschieht durch eine leichte Variation im Gebrauch von Mono und Polytypen in den Regeln A b s displaystyle mathtt Abs nbsp und L e t displaystyle mathtt Let nbsp In der Regel A b s displaystyle mathtt Abs nbsp wird die Wertvariable des Parameters der Funktion l x e displaystyle lambda x e nbsp dem Kontext als ein monomorpher Typ durch die Pramisse G x t e t displaystyle Gamma x tau vdash e tau nbsp hinzugefugt wahrend in der Regel L e t displaystyle mathtt Let nbsp die Variable die Umgebung in polymorpher Form G x s e 1 t displaystyle Gamma x sigma vdash e 1 tau nbsp betritt Obwohl in beiden Fallen die Anwesenheit von x im Kontext den Gebrauch der Generalisierungsregel fur jede Monotypvariable in der Zuordnung verhindert erzwingt diese Vorschrift dass ein Parameter x in einem l displaystyle lambda nbsp Ausdruck monomorph bleibt wahrend in einem let Ausdruck die Typvariablen bereits polymorph eingefuhrt werden konnen was Spezialisierungen ermoglicht Als Konsequenz dieses Reglements kann kein Typ fur l f f true f 0 displaystyle lambda f f textrm true f textrm 0 nbsp erschlossen werden da sich der Parameter f displaystyle f nbsp in monomorpher Position befindet wahrend let f l x x in f true f 0 displaystyle textbf let f lambda x x textbf in f textrm true f textrm 0 nbsp den Typ b o o l i n t displaystyle bool int nbsp darum ergibt weil f displaystyle f nbsp in einem let Ausdruck eingefuhrt und darum polymorph behandelt wird Beachte dass dieses Verhalten sich in starkem Gegensatz zu ublichen Definition let x e 1 in e 2 l x e 2 e 1 displaystyle textbf let x e 1 textbf in e 2 lambda x e 2 e 1 nbsp befindet was der Grund dafur ist die let Variante uberhaupt in die Syntax des Ausdrucks aufzunehmen Diese Unterscheidung wird let Polymorphismus genannt und ist dem HM eigentumlich Ubergang zum Algorithmus BearbeitenDa nun das Deduktionssystem des HMs zur Hand ist konnte man einen Algorithmus vorstellen diesen gegen die Regel uberprufen Alternativ kann man ihn moglicherweise durch einen genaueren Blick darauf wie die Regeln zusammenwirken und die Beweise geformt sind auch herleiten Dieser Weg wird nun im verbleibenden Rest dieses Artikels durch eine Fokussierung auf die moglichen Entscheidungen wahrend des Beweisens einer Typung beschritten Freiheitsgrade bei der Regelauswahl Bearbeiten Isoliert man in einem Beweise die Stellen an denen uberhaupt keine Auswahl moglich ist dann erhalt man die um die Ausdruckssyntax zentrierte erste Gruppe von Regeln die gleichsam das Gerust des Beweises bestimmt da jede der Schlussregeln genau einer Regel der Syntax entspricht wahrend zwischen den Pramissen und Schlussen dieser festen Regelanwendungen verbindende Ketten von I n s t displaystyle mathtt Inst nbsp and G e n displaystyle mathtt Gen nbsp auftreten konnen Alle Beweise mussen die so skizzierte Form haben Da die einzige Moglichkeit in einem Beweis im Hinblick auf die Regelauswahl diese I n s t displaystyle mathtt Inst nbsp und G e n displaystyle mathtt Gen nbsp Ketten sind legt die Gestalt der Beweise die Frage nahe ob man prazisieren kann wo diese Ketten benotigt werden Dies ist in der Tat moglich und fuhrt auf eine Variante des Regelsystems ohne diese beiden Regeln Syntaxgesteuertes Regelsystem Bearbeiten Syntaktisches Regelsystemx s G s t G x t V a r G e 0 t t G e 1 t G e 0 e 1 t A p p G x t e t G l x e t t A b s G e 0 t G x G t e 1 t G l e t x e 0 i n e 1 t L e t displaystyle begin array cl displaystyle frac x sigma in Gamma quad sigma sqsubseteq tau Gamma vdash x tau amp mathtt Var displaystyle frac Gamma vdash e 0 tau rightarrow tau quad quad Gamma vdash e 1 tau Gamma vdash e 0 e 1 tau amp mathtt App displaystyle frac Gamma x tau vdash e tau Gamma vdash lambda x e tau rightarrow tau amp mathtt Abs displaystyle frac Gamma vdash e 0 tau quad quad Gamma x bar Gamma tau vdash e 1 tau Gamma vdash mathtt let x e 0 mathtt in e 1 tau amp mathtt Let end array nbsp GeneralisierungG t a t a frei t frei G displaystyle bar Gamma tau forall hat alpha tau quad quad hat alpha textrm frei tau textrm frei Gamma nbsp Eine zeitgenossische Behandlung des HM verwendet ein rein syntaxgesteuertes Regelsystem nach Clement 5 als Zwischenschritt In diesem System ist die Spezialisierung direkt hinter der ursprunglichen V a r displaystyle mathtt Var nbsp Regel platziert und nun in diese eingemischt wahrend die Generalisierung mit in die L e t displaystyle mathtt Let nbsp Regel aufgenommen wurde Hierbei ist die Generalisierung zudem durch die Einfuhrung der Funktion G t displaystyle bar Gamma tau nbsp so bestimmt dass sie immer den allgemeinsten Typ erzeugt indem sie alle nicht in G displaystyle Gamma nbsp gebundenen Monotypvariablen quantifiziert Um zu uberprufen dass dieses neue Regelsystem S displaystyle vdash S nbsp zum Original D displaystyle vdash D nbsp aquivalent ist hat man zu zeigen dass G D e s G S e s displaystyle Gamma vdash D e sigma Leftrightarrow Gamma vdash S e sigma nbsp was in zwei Teilbeweise zerfallt G D e s G S e s displaystyle Gamma vdash D e sigma Leftarrow Gamma vdash S e sigma nbsp Korrektheit G D e s G S e s displaystyle Gamma vdash D e sigma Rightarrow Gamma vdash S e sigma nbsp Vollstandigkeit Wahrend man die Korrektheit durch Zerlegung der Regeln L e t displaystyle mathtt Let nbsp and V a r displaystyle mathtt Var nbsp von S displaystyle vdash S nbsp zu Beweisen in D displaystyle vdash D nbsp sehen kann ist ebenso erkennbar dass S displaystyle vdash S nbsp unvollstandig ist da man z B nicht zeigen kann dass S l x x a a a displaystyle vdash S lambda x x forall alpha alpha rightarrow alpha nbsp gilt sondern bestenfalls nur S l x x a a displaystyle vdash S lambda x x alpha rightarrow alpha nbsp Allerdings ist eine nur leicht schwachere Version der Vollstandigkeit nachweisbar 6 namlich G D e s G S e t G t s displaystyle Gamma vdash D e sigma Rightarrow Gamma vdash S e tau wedge bar Gamma tau sqsubseteq sigma nbsp was besagt dass man den Haupttyp fur einen Ausdruck in S displaystyle vdash S nbsp herleiten kann wenn man erlaubt den Beweis am Ende zu generalisieren Beachte dass S displaystyle vdash S nbsp im Vergleich zu D displaystyle vdash D nbsp nur noch Monotypen in den Urteilen seiner Regeln enthalt Freiheitsgrade bei der Regelinstanzierung Bearbeiten Bei gegebenem Ausdruck ist man innerhalb der Regeln selber frei die Instanzen fur alle Regel Variablen zu wahlen die nicht bereits durch die Ausdrucke festgelegt sind Dies sind die Instanzen fur die Typvariablen in den Regeln Arbeitet man darauf hin den Haupttyp zu zeigen dann lasst sich die Wahl auf das Aussuchen geeigneter Typen fur t displaystyle tau nbsp in V a r displaystyle mathtt Var nbsp und A b s displaystyle mathtt Abs nbsp einschranken Die Entscheidung fur eine angemessene Auswahl kann nicht lokal erfolgen aber deren Qualitat wird in den Pramissen von A p p displaystyle mathtt App nbsp erkennbar der einzigen Regel in der zwei unterschiedliche Typen namlich der des formalen und der des aktuellen Parameters zu einem zusammenkommen mussen Darum wurde eine allgemeine Strategie um einen Beweis zu finden darin bestehen die allgemeinste Annahme a f r e i G displaystyle alpha not in mathrm frei Gamma nbsp fur t displaystyle tau nbsp zu machen und diese sowie die in A b s displaystyle mathtt Abs nbsp zu treffende Wahl zu verfeinern bis alle durch die A p p displaystyle mathtt App nbsp Regeln geforderten Randbedingungen endlich erfullt sind Glucklicherweise sind hierfur weder Versuch und Irrtum noch irgendwelche Iterationen erforderlich da eine effektive Methode zur Berechnung aller notwendigen Entscheidungen bekannt ist die Unifikation nach Robinson in Verbindung mit dem sogenannten Union Find Algorithmus Um das Union Find Verfahren kurz zusammenzufassen erlaubt es bei gegebener Menge aller Typen in einem Beweis diese mittels der Prozedur u n i o n displaystyle mathtt union nbsp in Aquivalenzklassen zu teilen und mittels der Prozedur f i n d displaystyle mathtt find nbsp einen Reprasentanten zu bestimmen Das Wort Prozedur im Sinne von Nebenwirkung betonend wird das Reich der Logik hier verlassen um einen effektiven Algorithmus vorzubereiten Der Reprasentant von u n i o n a b displaystyle mathtt union a b nbsp ist hierbei so bestimmt dass falls sowohl a displaystyle a nbsp und auch b displaystyle b nbsp Typvariablen sind der Reprasentant beliebig eine von ihnen ist wahrend bei einer Vereinigung von einer Variablen und einer Anwendung letztere zum Reprasentanten gewahlt wird Hat man eine solche Implementierung des Union Find zur Hand dann kann man die Unifikation zweier Monotypen wie folgt formulieren unify ta tb ta find ta tb find tb wenn ta tb beide Anwendungen der Form D p1 pn mit identischen D n sind dann unify ta i tb i fur jeden korrespondierenden i ten Parameter sonst wenn wenigstens einer von ta tb eine Typvariable ist dann union ta tb sonst fehler Die Typen ta tb passen nicht zusammen Algorithmus W BearbeitenAlgorithmus Wx s G t i n s t s G x t V a r G e 0 t 0 G e 1 t 1 t n e w v a r u n i f y t 0 t 1 t G e 0 e 1 t A p p t n e w v a r G x t e t G l x e t t A b s G e 0 t G x G t e 1 t G l e t x e 0 i n e 1 t L e t displaystyle begin array cl displaystyle frac x sigma in Gamma quad tau mathit inst sigma Gamma vdash x tau amp mathtt Var displaystyle frac Gamma vdash e 0 tau 0 quad Gamma vdash e 1 tau 1 quad tau mathit newvar quad mathit unify tau 0 tau 1 rightarrow tau Gamma vdash e 0 e 1 tau amp mathtt App displaystyle frac tau mathit newvar quad Gamma x tau vdash e tau Gamma vdash lambda x e tau rightarrow tau amp mathtt Abs displaystyle frac Gamma vdash e 0 tau quad quad Gamma x bar Gamma tau vdash e 1 tau Gamma vdash mathtt let x e 0 mathtt in e 1 tau amp mathtt Let end array nbsp Die Prasentation des Algorithmus W wie er im Kasten an der Seite gezeigt wird weicht nicht nur signifikant vom Original 4 ab sondern stellt auch einen erheblichen Fehlgebrauch der Notation logischer Regeln dar da er Nebeneffekte mit einschliesst Dies ist hier dadurch legitimiert um einen direkten Vergleich mit S displaystyle vdash S nbsp zu ermoglichen und zugleich eine effektive Implementierung anzugeben Die Regeln spezifizieren nun eine Prozedur mit Parametern G e displaystyle Gamma e nbsp und Resultat t displaystyle tau nbsp im Schluss wobei die Ausfuhrung der Pramissen von links nach rechts verlauft Alternativ zu einer Prozedur konnen die Regeln als eine Attributierung mit denselben Anmerkungen bzgl der Nebeneffekte angesehen werden Die Prozedur i n s t s displaystyle inst sigma nbsp spezialisiert den Polytyp s displaystyle sigma nbsp indem sie den Term kopiert und die darin enthaltenen gebundenen Variablen konsistent durch global neue Monotypvariablen ersetzt n e w v a r displaystyle newvar nbsp erzeugt eine neue Monotypvariable In ahnlicher Weise hat G t displaystyle bar Gamma tau nbsp eine Kopie des Typs herzustellen in der global neue Typvariablen fur die Quantifikation eingefuhrt werden um ungewollte Bindungen zu vermeiden Insgesamt verfahrt der Algorithmus nun indem er immer die allgemeinst mogliche Auswahl triff und die Spezialisierung der Unifikation uberlasst die ihrerseits das allgemeinst mogliche Resultat erzeugt Wie oben angemerkt ist das Ergebnis t displaystyle tau nbsp am Ende noch einmal zu G t displaystyle bar Gamma tau nbsp zu generalisieren um den Haupttyp fur einen gegebenen Ausdruck zu erhalten Da die im Algorithmus verwendeten Prozeduren Kosten nahe O 1 displaystyle O 1 nbsp haben sind die Gesamtkosten des Verfahrens nahezu linear zur Grosse des Ausdrucks fur den ein Typ zu inferieren ist Es steht damit in starkem Kontrast zu vielen anderen Versuchen ein Typinferenzverfahren herzustellen die sich oft als NP schwer wenn nicht unentscheidbar bzgl Terminierung herausgestellt haben Mithin hat HM denselben Durchsatz den das beste voll informierte Typprufungsverfahren haben kann Typprufung heisst hier dass ein Algorithmus keinen Beweis zu finden hat sondern diesen nur zu uberprufen braucht Die Effizienz ist aus zwei Grunden geringfugig niedriger Zum ersten sind die Bindungen der Typvariablen im Kontext zu verwalten um die Berechnung von G t displaystyle bar Gamma tau nbsp zu erlauben Ferner ist ein occurs check erforderlich um die Entstehung rekursiver Typen wahrend Unifikation zu verhindern Ein Beispiel fur einen solchen Fall ist l x x x displaystyle lambda x x x nbsp fur das kein Typ mit dem HM hergeleitet werden kann Da in der Praxis die Typen nur kleine Terme sind und sich zudem nicht zu expandierenden Strukturen aufbauen kann man sie in der Komplexitatsanalyse als kleiner als eine bestimmte Konstante betrachten so dass die O 1 Kosten gewahrt bleiben Der Algorithmus W im Original Bearbeiten In der Originalpublikation 4 wird der Algorithmus formaler in einem Substitutionsstil beschrieben statt durch Nebeneffekte wie in der Methode oben In letzter Form kummert sich der Nebeneffekte unsichtbar um alle Stellen in denen Typvariablen verwendet werden Explizite Verwendung der Substitution macht nicht nur den Algorithmus schwerer zu lesen da die Nebeneffekte praktisch uberall auftreten sondern vermittelt auch den falschen Eindruck dass die Methode teuer ist Wird sie hingegen mit rein funktionalen Mitteln oder zum Zweck des Beweises der Aquivalenz zum Deduktionssystem implementiert ist voll Explizitheit naturlich notwendig und die Originalformulierung eine notwendige Verfeinerung Weitere Themen BearbeitenRekursive Definitionen Bearbeiten Eine zentrale Eigenschaft des Lambda Kalkuls ist dass rekursive Definitionen nicht elementar sind sondern mit Hilfe des Fixpunktkombinators ausgedruckt werden konnen In der Originalpublikation 4 wird angemerkt dass Rekursion mit dem Typ f i x a a a a displaystyle fix forall alpha alpha rightarrow alpha rightarrow alpha nbsp dieses Kombinators realisiert werden kann Eine mogliche rekursive Definition kann damit als r e c v e 1 i n e 2 l e t v f i x l v e 1 i n e 2 displaystyle mathtt rec v e 1 mathtt in e 2 mathtt let v fix lambda v e 1 mathtt in e 2 nbsp formuliert werden Alternativ ist eine Erweiterung der Ausdruckssyntax und eine zusatzliche Typregel moglich mit G G e 1 t 1 G G e n t n G G e t G r e c v 1 e 1 a n d a n d v n e n i n e t R e c displaystyle displaystyle frac Gamma Gamma vdash e 1 tau 1 quad dots quad Gamma Gamma vdash e n tau n quad Gamma Gamma vdash e tau Gamma vdash mathtt rec v 1 e 1 mathtt and dots mathtt and v n e n mathtt in e tau quad mathtt Rec nbsp mit G v 1 t 1 v n t n displaystyle Gamma v 1 tau 1 dots v n tau n nbsp G v 1 G t 1 v n G t n displaystyle Gamma v 1 bar Gamma tau 1 dots v n bar Gamma tau n nbsp Hierin sind grundsatzlich A b s displaystyle mathtt Abs nbsp und L e t displaystyle mathtt Let nbsp zusammengemischt wobei die rekursiv definierten Variablen monomorph behandelt werden wenn sie links vom i n displaystyle mathtt in nbsp auftreten aber polymorph rechts davon Diese Formulierung fasst die Essenz des let Polymorphismus vielleicht am besten zusammen Anmerkungen Bearbeiten Polytypen werden in der Originalpublikation als Typ Schemata type schemes bezeichnet Die parametrischen Typen D t t displaystyle D tau dots tau nbsp sind in der Originalpublikation uber HM nicht enthalten und fur die Darstellung der Methode auch nicht erforderlich Keine der Inferenzregeln ist fur sie zustandig oder wurde ihre Abwesenheit bemerken Dasselbe gilt fur die nichtparametrischen primitiven Typen im betreffenden Papier Die gesamte Maschinerie polymorpher Typinferenz kann ohne sie definiert werden Sie sind hier teils der Beispiele wegen aufgenommen aber vor allem da sich die Natur des HM ganz und gar um polymorphe Typen dreht Der parametrische Polymorphismus tritt im Original nur in spezieller Form durch den in den Inferenzregeln fest verdrahteten Funktionstyp t t displaystyle tau rightarrow tau nbsp auf der zwei polymorphe Parameter hat und hier nur als spezieller Fall behandelt wird Einzelnachweise Bearbeiten R Hindley 1969 The Principal Type Scheme of an Object in Combinatory Logic Transactions of the American Mathematical Society Vol 146 S 29 60 JSTOR 1995158 Milner 1978 A Theory of Type Polymorphism in Programming Journal of Computer and System Science JCSS 17 S 348 374 online Luis Damas 1985 Type Assignment in Programming Languages PhD thesis University of Edinburg CST 33 85 a b c d e Damas Milner 1982 Principal type schemes for functional programs 9th Symposium on Principles of programming languages POPL 82 S 207 212 ACM PDF Memento vom 24 Marz 2012 im Internet Archive Clement 1987 The Natural Dynamic Semantics of Mini Standard ML TAPSOFT 87 Vol 2 LNCS Vol 250 pp 67 81 Jeff Vaughan A proof of correctness for the Hindley Milner type inference algorithm Memento vom 24 Marz 2012 im Internet Archive PDF 152 KB Abgerufen von https de wikipedia org w index php title Typinferenz nach Hindley Milner amp oldid 237782475