Ich verwende diesen Typ, um über Strings zu argumentieren, auf denen Decidable Parsing ausgeführt werden kann:
%Vor%Zum Beispiel definieren Sie die Ziffern [0-9] wie folgt:
%Vor%Dann können wir folgende Funktionen haben:
%Vor% Diese s2n
-Funktion funktioniert jetzt gut zur Kompilierzeit, aber das ist an sich nicht sehr nützlich. Um es zur Laufzeit zu verwenden, müssen wir den Beweis Every Digit (unpack s)
erstellen, bevor wir die Funktion verwenden können.
Also ich denke ich möchte jetzt so etwas wie diese Funktion schreiben:
%Vor% Das oder wir wollen entweder einen Beweis der Mitgliedschaft oder einen Nachweis der Nicht-Mitgliedschaft zurückgeben, aber ich bin mir nicht ganz sicher, wie ich eines dieser Dinge allgemein machen soll. Also habe ich versucht, die Maybe
Version nur für Charaktere zu machen:
Aber dann bekomme ich diesen Unifikationsfehler:
%Vor% Aber p
ist vom Typ Char -> Type
. Ich bin mir nicht sicher, was diesen Unifikationsfehler verursacht, aber denke, dass das Problem mit zusammenhängen könnte meine vorherige Frage .
Ist das eine vernünftige Herangehensweise an das, was ich versuche? Ich habe das Gefühl, dass es im Moment ein wenig zu viel Arbeit ist und allgemeinere Versionen dieser Funktionen möglich sein sollten. Es wäre schön, wenn das auto
Schlüsselwort zum Schreiben einer Funktion verwendet werden könnte, gibt es eine Maybe proof
oder eine Either proof proofThatItIsNot
, ähnlich wie die DecEq
Klasse funktioniert.
Die Fehlermeldung ist korrekt: Sie haben einen Wert vom Typ Type
angegeben, aber Sie benötigen einen Wert vom Typ p '0'
. Sie haben auch Recht, dass p
vom Typ Char -> Type
ist und daher p '0'
vom Typ Type
ist. % Co_de% hat jedoch nicht den Typ p '0'
.
Vielleicht wäre das Problem einfacher mit einfacheren Typen zu sehen: p '0'
hat den Typ 3
und Int
hat den Typ Int
, aber Type
hat nicht den Typ Int
.
Nun, wie beheben wir das Problem? Nun, Int
ist ein Prädikat, was bedeutet, dass es Typen konstruiert, deren Bewohner Beweise für dieses Prädikat sind. Also wäre der Wert des Typs p
, den wir bereitstellen müssen, ein Beweis, in diesem Fall ein Beweis dafür, dass p '0'
eine Ziffer ist. '0'
ist ein solcher Beweis. Aber in der Signatur von Zero
spricht die Variable every
nicht von Ziffern: Es ist ein abstraktes Prädikat, über das wir nichts wissen. Aus diesem Grund gibt es keine Werte, die wir anstelle von p
verwenden könnten. Wir müssen stattdessen den Typ von p '0'
ändern.
Eine Möglichkeit wäre, eine speziellere Version von every
zu schreiben, die nur für das bestimmte Prädikat every
funktioniert, anstatt für eine beliebige Digit
:
Anstatt den Wert p
an einer Stelle falsch zu verwenden, die einen Wert vom Typ p '0'
benötigt, habe ich den Wert p '0'
an einer Stelle verwendet, die jetzt einen Wert vom Typ Zero
benötigt.
Eine andere Möglichkeit bestünde darin, Digit '0'
so zu ändern, dass zusätzlich zu dem Prädikat every
, das für jeden p
einen Proof-Typ gibt, auch eine Proof-Funktion Char
erhalten würde, die das entsprechende ergibt Beweiswert für jedes mkPrf
, wenn möglich.
Ich habe keinen Mustervergleich mehr auf der Seite Char
, stattdessen frage ich Char
, um mkPrf
zu untersuchen. Ich mustere dann das Ergebnis, um zu sehen, ob es einen Beweis gefunden hat. Es ist die Implementierung von Char
, die Muster-Übereinstimmungen in mkPrf
.
In der Implementierung von Char
konstruieren wir wieder einen Beweis für den konkreten Typ mkPrf
anstelle des abstrakten Typs Digit '0'
, also ist p '0'
ein akzeptabler Beweis.
Tags und Links parsing idris unification decidable