2010-08-05 14 views
8

Ich entwickle einige OCaml-Algorithmen, die einige Teile als "steckbar" benötigen, so dass ein Teil der Berechnung bestimmten Berechnern überlassen wird.Verwenden von Funktoren als Schnittstellen in OCaml

Nur um ein Beispiel zu machen nehme ich eine Signatur wie diese haben:

module type Algorithm = sig 
    val feed : float -> unit 
    val nth : int -> (float -> float) 
end 

und zwei verschiedene Implementierungen, die Alg1 und Alg2 sein wird. Dieses Algorithm Modul sollte die Schnittstelle für verschiedene Implementierungen wie diese beiden darstellen.

Jetzt brauche ich eine andere Komponente, machen wir es Executor nennen, dass das Modul sein, das Alg1 oder Alg2 Throught ihre Schnittstelle verwendet ..

Lesung über functors es scheint, dass ich einen Funktor brauchen sollte, die eine Algorithm nimmt und eine ConcreteExecutor mit einer spezifischen Implementierung des Algorithmus ich brauche. So dass Executor ist eine Art von Modul, das über eine seiner Komponenten parametriert ist.

Bin ich richtig? Ist es der beste Weg, um das zu bekommen, was ich brauche? Ich frage mich, ob Thinkgs wie diese sind, weil ich aus einem Java/C++ - Hintergrund komme, also bin ich gewohnt, Interfaces und abstrakte Klassen zu verwenden, und ich muss in dieser Funktor/Modul-Abstraktionsproblem in der richtigen Weise gehen.

Welche ist die richtige Syntax, um zu erhalten, was ich will?

Vielen Dank im Voraus

+2

Dies ist wirklich ein großer Einsatz von Funktoren. Ich benutze sie in einer Labyrinthgenerierungsanwendung. Schließen Sie einen Algorithmus und eine Labyrinthdarstellung an, und Sie sind aus. Arbeitet noch an der Ausgabe, die ein anderer Funktor sein könnte, um SVG, GraphViz, PDF und PNG zu unterstützen. – nlucaroni

+1

@nlucaroni - ist der Code zu deiner Labyrinthgenerierung überall verfügbar? – aneccodeal

Antwort

4

Yup, es ist wie functors klingt, was Sie wollen. In der Tat können Sie sehen, wie die Standardbibliothek Funktoren verwendet, da der Quellcode verfügbar ist. Auf meinem Rechner befindet es sich unter /usr/lib/ocaml/3.10.2/. Als Beispiel enthält set.mli folgendes:

module type OrderedType = 
    sig 
    type t 
    val compare : t -> t -> int 
    end 

module type S 
    sig 
    ... 
    end 

module Make (Ord : OrderedType) : S with type elt = Ord.t 

Wenn Sie einen Satz in OCaml verwenden möchten Sie tun:

module SSet = Set.Make(String);; 

So mit Ihrem Code, Algorithmus ersetzt OrderedType, ALG1/Alg2 ersetzt Zeichenfolge, Executor ersetzt Make und ConcreteExecutor ist das Ergebnis von Executor (Alg1/Alg2). Sie werden auch bemerken, dass string.mli/ml keine Erwähnung von OrderedType enthält. String ist ein OrderedType, da er einen Typ t hat, der von einem Funktionsvergleich verwendet wird. Sie müssen nicht ausdrücklich angeben, dass String ein OrderedType ist.

+0

Sie müssen ocaml aktualisieren. :) – nlucaroni

+0

Ha! Das ist die Version auf einer Maschine, auf die ich keinen Root-Zugriff habe. Meine Heim-Maschine ist aktueller (obwohl wer weiß, wann Debian 3.12 bekommt?). –

+0

Es kann einige Zeit dauern, aber Sie wissen, dass mangelnde Kompatibilität zwischen OCaml-Versionen für die Verzögerungen verantwortlich ist, nicht wahr? Die Debian "OCaml Maintainer" müssen sicherstellen, dass alle OCaml-Pakete in Debian mit der neuen Version kompiliert werden, und sie alle auf einmal wechseln. Sie machen einen tollen Job und das ist nicht ihre Schuld. –