Nun, etwas, das als Parametrizität bekannt ist, sagt uns, dass es, wenn wir die reine Teilmenge von ML betrachten (dh keine unendliche Rekursion refund all das seltsame Zeug), keine andere Möglichkeit gibt, eine Funktion mit diesem Typ zu definieren, als die, die das Leere zurückgibt Liste.
Alles begann mit Wadlers Artikel „ Theorems for free! ”. Dieses Papier sagt uns im Grunde zwei Dinge:
- Wenn wir Programmiersprachen betrachten, die bestimmte Bedingungen erfüllen, können wir einige coole Theoreme ableiten, indem wir nur die Typensignatur einer polymorphen Funktion betrachten (dies wird als Parametrizitätssatz bezeichnet).
- ML (ohne unendliche Rekursion
refund all das seltsame Zeug) erfüllt diese Bedingungen.
Aus dem Parametrizität Theorem wissen wir , dass , wenn wir eine Funktion haben f : 'a list -> 'b list, dann für alle 'a, 'b, 'c, 'dund für alle Funktionen g : 'a -> 'c, die h : 'b -> 'dwir haben:
map h ∘ f = f ∘ map g
(Beachten Sie, flinks hat Typ 'a list -> 'b listund frechts ist 'c list -> 'd list.)
Wir können frei wählen, was gwir wollen, also lassen Sie 'a = 'cund g = id. Jetzt haben wir map id = id(leicht durch Induktion der Definition von zu beweisen map):
map h ∘ f = f
Jetzt lass 'b = 'd = boolund h = not. Nehmen wir für einige an zs : bool list, dass es passiert f zs ≠ [] : bool list. Es ist klar, dass map not ∘ f = fdas nicht gilt, weil
(map not ∘ f) zs ≠ f zs
Wenn das erste Element der Liste rechts ist true, dann ist links das erste Element falseund umgekehrt!
Dies bedeutet, dass unsere Annahme falsch ist und f zs = []. Sind wir fertig? Nein.
Wir gingen davon aus, dass 'bist bool. Wir haben gezeigt , dass , wenn fmit Typ aufgerufen wird f : 'a list -> bool listfür jede 'a, fmuss immer die leere Liste zurück. Kann es sein, dass wenn wir anrufen f, f : 'a list -> unit listes etwas anderes zurückgibt? Unsere Intuition sagt uns, dass dies Unsinn ist: Wir können einfach keine reine ML-Funktion schreiben, die immer die leere Liste zurückgibt, wenn wir möchten, dass sie uns eine Liste von Booleschen Werten gibt, und ansonsten möglicherweise eine nicht leere Liste zurückgibt! Dies ist jedoch kein Beweis.
Was wir sagen wollen, ist, dass fes einheitlich ist : Wenn es immer die leere Liste für zurückgibt bool list, muss es die leere Liste für unit listund im Allgemeinen für jede zurückgeben 'a list. Genau darum geht es beim zweiten Punkt in der Aufzählungsliste am Anfang meiner Antwort.
Das Papier sagt uns , dass in ML fnehmen muß damit verbundene Werte zu verwandt denjenigen. Ich werde nicht in die Details über die Beziehungen, ist es genug , um zu sagen , dass Listen werden im Zusammenhang , wenn und nur wenn sie die gleiche Länge haben und ihre Elemente sind paarweise im Zusammenhang (das heißt, [x_1, x_2, ..., x_m]und [y_1, y_2, ..., y_n]beziehen sich, wenn und nur wenn m = nund x_1bezieht sich auf y_1und x_2ist verwandt mit y_2und so weiter). Und der Spaß daran ist, in unserem Fall, da fpolymorph ist, wir können definieren , jede Beziehung auf die Elemente von Listen!
Lassen Sie uns holen jeder 'a, 'bund schauen Sie sich f : 'a list -> 'b list. Nun sieh dir an f : 'a list -> bool list; Wir haben bereits gezeigt, dass in diesem Fall fimmer die leere Liste zurückgegeben wird. Wir postulieren nun, dass alle Elemente von 'asich auf sich selbst beziehen (denken Sie daran, wir können jede gewünschte Beziehung wählen), dies impliziert, dass sich jede zs : 'a listauf sich selbst bezieht. Wie wir wissen, werden fverwandte Werte mit verwandten Werten in Verbindung gebracht. Dies bedeutet, dass sie f zs : 'b listverwandt sind f zs : bool list, aber die zweite Liste hat eine Länge von Null, und da die erste Liste damit verwandt ist, ist sie auch leer.
Der Vollständigkeit halber möchte ich erwähnen, dass es in der Originalarbeit des Wadlers einen Abschnitt über die Auswirkungen der allgemeinen Rekursion (mögliche Nichtbeendigung) gibt, und es gibt auch eine Arbeit , die freie Theoreme in Gegenwart von untersucht seq.