Eine Möglichkeit, Typen als Logik zu interpretieren, sind die Existenzbedingungen für Werte des Rückgabetyps. Also f :: a -> [a]
wir den Satz , daß, wenn es einen Wert vom Typ existiert a
, gibt einen Wert vom Typ existiert [a]
. Die Implementierung der Funktion ist der Beweis des Satzes.
Hier ist eine detailliertere Erklärung:
Grundsätzlich können wir mit Datenkonstruktoren ähnliche Dinge wie Summen und Produkte (ODER und UND) erstellen, aber wir können mehrere Varianten haben und den Typ speziell mit einem Namen "kennzeichnen", um ihn zu unterscheiden (wie den Namen List
).
Sie lassen uns sie auch rekursiv bauen: für einen Satz ein, der Satz [ a ] kann als Lösung der Gleichung angesehen werden
x ( a )⟺⊤ ∨ ( a ∧ x ( a ) )
Die Dinge werden etwas klarer, wenn Sie die Definition von List mit einem Pseudocode im GADT-Stil schreiben, ähnlich dem, was Sie in Agda sehen würden:
data List : Type -> Type where
Nil : ∀ a . List a
Cons : ∀ a . a -> List a -> List a
Dies gibt uns zwei Dinge: die Konstruktoren (oder Funktionen), die als Axiome für die Sätze von dienen List
, und Axiome für die Musteranpassung oder Dekonstruktion.
Grob gesagt werden die folgenden Axiome in die Logik eingeführt:
- Für jeden Vorschlag ein, [ a ] hält.
- Wenn ein hält, und [ a ] hält dann [ a ] hält
- Wenn [ a ] gilt dann auch nicht ⊤ hält, oder a ∧ [ a ] hält.
Diese sind ziemlich nutzlos, wenn sie als Logik interpretiert werden, da wir es immer wissen ⊤ hält, dort zu dekonstruieren gibt uns nicht viele nützliche Informationen
Ohne Quantifizierer oder leistungsfähigere Typerweiterungen (GADTs, Typfamilien, abhängige Typen usw.) können Sie feststellen, dass wir interessante Dinge nicht wirklich beweisen können, weshalb Sie häufig nicht viel über die Interpretation von Standard-Haskell-Typen als Logik sehen .
Cons : ∀ a . a -> List a
: meintest duCons : ∀ a . a -> List a -> List a
?Listentypen sind als Vorschlag etwas seltsam. Sie entsprechen nicht wirklich etwas direkt Bekanntem, aber es ist leicht zu erkennen, was sie entsprechen. Da es
[a]
keine gibt, können Sie immer nachweisen,a
dass Listentypen immer sehr einfach zu beweisen sind, insbesondere sind sie trivial einer bereits nachgewiesenen Tautologie äquivalent. Es ist also etwas uninteressant, sie vorzustellen. Darüber hinaus hat die Eliminierungsregel ein Problem. Sie müssen nämlich etwas beweisen[]
, um eine Liste zu entfernen, die Ihnen keine neuen Annahmen gibt. Daher kann ich normalerweise jeden Beweis, der eine Listeneliminierung verwendet, in einen Beweis umwandeln, der ihn nicht verwendet. Ich könnte jedoch etwas über die Liste wissen, das widersprach, dass sie leer ist. In diesem Fall ist sie viel interessanter.Die meiste Zeit ist es ein bisschen langweilig, aber manchmal ist es dank der Relevanz der Beweise tatsächlich etwas interessant. Haskell hat jedoch keine Beweisrelevanz, daher sind Listen in Haskell nur langweilig.
In gewissem Sinne (ich fummele hier an Sachen) entsprechen Listen in Haskell etwas, das dem ständig wahren booleschen Operator entspricht. Negiert also keinen Booleschen Wert, id behält ihn bei, und das, was sich in dieser Liste verhält, gibt immer wahr, egal was Sie daran anschließen.
quelle