2008-08-30 7 views
11

Ich schreibe einen Interpreter für eine experimentelle Sprache. Drei der wichtigsten Konstrukte der Sprache sind Definitionen, Anweisungen und Ausdrücke. Definitionen können Anweisungen und Ausdrücke enthalten, Anweisungen können Definitionen und Ausdrücke enthalten und eine Art von Ausdruck kann Anweisungen enthalten. Ich vertrete alle diese mit Union-Typen, so dass ich leicht Mustererkennung auf ihnen verwenden kann. Im Idealfall möchte ich den Code für diese in verschiedenen Dateien ablegen, aber OMake beschwert sich über zirkuläre Abhängigkeitsprobleme. Soweit ich weiß, sind zirkuläre Typdefinitionen in Modulen nicht erlaubt.Umgang mit zirkulären Abhängigkeiten in OCaml

Der einzige Weg, ich weiß, das zu lösen ist, alle drei Typen auf einmal zu definieren:

type defn = ... 
and stmt = ... 
and expr = ... 

es so den gesamten Code erfordert für die Typen in der gleichen Datei zu sein scheint. Gibt es einen Weg dazu? Wie gehen Sie mit zirkulären Definitionen in Ihrem Code um?

Antwort

15

Rekursive Definitionen müssen in derselben Datei erscheinen. Wenn Sie Definitionen, Anweisungen und Ausdrücke in separate Module unterteilen möchten, können Sie dies unter Verwendung von recursive modules tun, sie müssen jedoch weiterhin in derselben Datei angezeigt werden. Die DAG-Abhängigkeit von Dateiabhängigkeiten ist einer der Nachteile von OCaml.

type ('stmt, 'expr) defn = ... 
type ('defn, 'expr) stmt = ... 
type ('defn, 'stmt) expr = ... 

Diese Technik wird als „Aufhebung der Bindung der rekursiven Knoten“ (in Bezug auf Gordians Knoten) und wurde in einem OCaml Journal Artikel beschrieben:

12

Dies wird durch Parametrisierung Ihre Typen über die Typen sie beziehen sich auf leicht gelöst .

Prost, Jon Harrop.

3

Eine andere häufig verwendete Lösung besteht darin, die Typen in den Schnittstellen zu abstrahieren. Da die Typen in den Schnittstellen abstrakt sind, sind diese Schnittstellen nicht rekursiv abhängig. In den Implementierungen können Sie die Typen angeben, und da die Implementierungen nur von den Schnittstellen abhängen, sind sie auch nicht rekursiv.

Das einzige Problem ist, dass Sie mit dieser Lösung keinen Mustervergleich mehr für diese Typen außerhalb ihrer Implementierung durchführen können.

Persönlich, aber es ist wahrscheinlich eine Frage des Geschmacks, ich möchte alle Arten von meinem Programm in einem Modul definiert haben (ich denke, es hilft in der Lesbarkeit des Programms). Also, diese Einschränkung von OCaml ist nicht wirklich ein Problem für mich.

Verwandte Themen