Es ist bedauerlich, dass ein Großteil der Literatur zu diesem Thema sehr dicht ist. Ich war auch in deinen Schuhen. Ich habe meine erste Einführung in das Thema von Programmiersprachen: Anwendungen und Interpretation bekommen
http://www.plai.org/
Ich werde versuchen, die abstrakte Idee zusammenzufassen, gefolgt von Details, die ich nicht sofort offensichtlich fand. Zunächst kann an eine Typinferenz gedacht werden, um Einschränkungen zu generieren und dann zu lösen. Um Einschränkungen zu generieren, durchlaufen Sie den Syntaxbaum und generieren eine oder mehrere Einschränkungen für jeden Knoten. Wenn der Knoten beispielsweise ein +
Operator ist, müssen die Operanden und die Ergebnisse alle Zahlen sein. Ein Knoten, der eine Funktion anwendet, hat denselben Typ wie das Ergebnis der Funktion usw.
Für eine Sprache ohne let
können Sie die oben genannten Einschränkungen blind durch Ersetzen lösen. Beispielsweise:
(if (= 1 2)
1
2)
Hier können wir sagen, dass die Bedingung der if-Anweisung boolesch sein muss und dass der Typ der if-Anweisung mit dem Typ ihrer then
und else
-Klauseln identisch ist . Da wir Zahlen kennen 1
und 2
sind, wissen wir durch Substitution, dass die if
Aussage eine Zahl ist.
Wo die Dinge böse werden und was ich eine Weile nicht verstehen konnte, ist das Thema:
(let ((id (lambda (x) x)))
(id id))
Hier haben wir uns an id
eine Funktion gebunden , die alles zurückgibt, was Sie übergeben haben, auch bekannt als Identitätsfunktion. Das Problem ist, dass der Typ des Funktionsparameters x
bei jeder Verwendung von unterschiedlich ist id
. Die zweite id
ist eine Funktion vom Typ a -> a
, wo a
alles sein kann. Der erste ist vom Typ (a -> a) -> (a -> a)
. Dies ist als Let-Polymorphismus bekannt. Der Schlüssel besteht darin, Einschränkungen in einer bestimmten Reihenfolge zu lösen: Lösen Sie zuerst Einschränkungen für die Definition von id
. Das wird sein a -> a
. Dann können frische, separate Kopien des Typs von id
in die Einschränkungen für jeden Ort id
eingesetzt werden, zum Beispiel a2 -> a2
und a3 -> a3
.
Das wurde in Online-Ressourcen nicht ohne weiteres erklärt. Sie werden den Algorithmus W oder M erwähnen, aber nicht, wie sie beim Lösen von Einschränkungen funktionieren oder warum der Let-Polymorphismus nicht beeinträchtigt wird: Jeder dieser Algorithmen erzwingt eine Reihenfolge beim Lösen der Einschränkungen.
Ich fand diese Ressource äußerst hilfreich, um Algorithmus W, M und das allgemeine Konzept der Erzeugung und Lösung von Einschränkungen miteinander zu verknüpfen. Es ist ein wenig dicht, aber besser als viele:
http://www.cs.uu.nl/research/techreps/repo/CS-2002/2002-031.pdf
Viele der anderen Papiere dort sind auch nett:
http://people.cs.uu.nl/bastiaan/papers.html
Ich hoffe, das hilft, eine etwas trübe Welt zu klären.