Ich versuche einen Weg zu finden, um die normale rekursive Notation zu übersetzen als | fib | Funktionieren Sie unterhalb eines Pfeils und behalten Sie so viel von der Struktur der rekursiven Notation als möglich. Außerdem würde ich schaue gerne den Pfeil an. Dazu habe ich einen Datentyp erstellt, der ein enthält Konstruktor für jede Arrow {..} -Klasse:
Fib:
%Vor%Mein R-Datentyp, die Instanzen für diesen Datentyp bestehen aus dem Mapping zum entsprechenden Konstruktor:
%Vor%Übersetzen der | fib | Funktion von oben führte zuerst zu der folgende Definition. Es ist jedoch aufgrund des Prozesses nicht erlaubt die RHS der Deklaration für | fibz |. Ich weiß, dass die Grammatik des Arrow Notation verhindert dies, aber was ist der Grund dafür das?
%Vor%Überschreiben der obigen Funktion, um eine let-Anweisung zu kompilieren. Jedoch, hier entsteht mein zweites Problem. Ich möchte in der Lage sein, die Rekursion, wo es passiert. In diesem Fall | fibz | ist ein unendlicher Baum. Ich möchte die Rekursion in fibz einfangen, ich Ich hoffe, der Rec würde mir dabei in Kombination mit | loop | helfen aber vielleicht liege ich falsch?
%Vor%Grundsätzlich ist es möglich, diese Art von Rekursion zu beobachten? (Vielleicht sogar innerhalb der Grenzen der Arrow Notation) könnte ich vielleicht hinzufügen ein anderer Konstruktor wie Fix. Vielleicht sollte ich in der Lage sein, die Bindung von Variablen zu beobachten, so dass die Bezugnahme auf sie möglich wird. Dies würde jedoch außerhalb des Umfangs der Pfeile liegen.
Irgendwelche Gedanken dazu?
Update 1:
Ich komme mit dieser Form außerhalb der Pfeilnotation. Dadurch wird die Rekursion innerhalb von app
ausgeblendet und ich habe daher eine endliche Darstellung des Arrows. Ich möchte jedoch immer noch z.B. Ersetzen Sie den Aufruf von fib
in app
durch eine optimierte Version von fib
.
Dieser Code entspricht in Pfeilnotation folgendem:
%Vor% Sie können fib
in Form einer Schleife schreiben, zum Beispiel so:
Aber das ist wirklich nur eine künstliche Schleife zu einem Problem, das es nicht braucht, und es nicht wirklich kaufen Sie auch viel in Bezug auf die Beobachtbarkeit. Sie können sehen, dass eine Art Schleife existiert, aber ich denke, es ist unmöglich, den Ort der Rekursion genau zu bestimmen.
In der verdinglichten Darstellung sind alle Aufrufe von anderen Pfeilen im Wesentlichen "inline" und dies beinhaltet Aufrufe an den gleichen Pfeil. Sie können diese Call-Sites zunächst nicht wirklich erkennen, ganz zu schweigen davon, herauszufinden, welcher Pfeil aufgerufen wird. Ein weiteres Problem bei der Pfeilretifizierung besteht darin, dass viele interessante Informationen darüber, wie Eingaben weitergegeben werden, innerhalb von Arr
blackhole verloren gehen.
Ich bin sicher kein Experte für Pfeile und ich hoffe, dass jemand mich falsch ausweist, aber ich bin geneigt zu glauben, dass das, was Sie erreichen wollen, unmöglich zuverlässig oder zumindest höchst unpraktisch ist. Eine Ressource, an die ich denken kann, könnte Ihnen helfen, das Papier Typ-sichere beobachtbare Freigabe in Haskell und das Paket data-retify .
Sie können fib vollständig mit einer Category vereinheitlichen, so dass Sie Funktionen definieren können, um Ihren Code auf Festplatte zu speichern und zurück zu laden. Es ist jedoch ein kleines bisschen hässlich.
%Vor% R
hier ist ein indiziertes Monoid, das sich als ein Category
herausstellt. Die beiden Typparameter to R
repräsentieren die Typensignatur des Stacks vor und nach einer Operation. Ein Stapel als Programmstapel, wie im Assemblercode. Die Tupel in den Stapeltypen bilden eine heterogene Liste, um jedes der Elemente auf dem Stapel einzugeben. Alle Operationen (außer If) nehmen Null Parameter und manipulieren nur den Stapel. Das If benötigt zwei Codeblöcke und gibt Code zurück, der keine Parameter akzeptiert und nur den Stapel manipuliert.
Rec
wird für die Rekursion verwendet. Ein Interpreter würde einen eindeutigen Namen (als Ganzzahl) für die rekursive Funktion finden, dann würde sich die rekursive Funktion auf diesen Namen mit Deref
beziehen, um eine Rekursion mit sich selbst zu bilden.
Diese Art von Ding könnte man sich als eine konkatenative Programmiersprache (wie eine EDSL) wie Forth vorstellen, außer dass sie Typ-Sicherheit für die Werte auf dem Stapel hat.