2009-09-20 8 views
16

Ich möchte OCaml verwenden, um Datensätze zu generieren und Vergleiche zwischen ihnen zu machen. Ich habe die Dokumentation für Modultypen wie Set.OrderType, Set.Make usw. gesehen, aber ich kann nicht herausfinden, wie man ein Set initialisiert oder anderweitig benutzt.OCaml: Module setzen

Antwort

28

Sets werden über eine funktorische Schnittstelle definiert. Für jeden gegebenen Typ müssen Sie ein Set Modul für diesen Typ unter Verwendung des Set.Make Funktors erstellen. Ein unglückliches Versehen der Standardbibliotheken besteht darin, dass sie Set Instanzen für die eingebauten Typen nicht definieren. In den meisten einfachen Fällen genügt es, Pervasives.compare zu verwenden. Hier ist eine Definition, die für int funktioniert:

module IntSet = Set.Make( 
    struct 
    let compare = Pervasives.compare 
    type t = int 
    end) 

Das Modul IntSet den Set.S-Schnittstelle implementieren. Jetzt können Sie auf Gruppen arbeiten die IntSet Modul:

let s = IntSet.empty ;; 
let t = IntSet.add 1 s ;; 
let u = IntSet.add 2 s ;; 
let tu = IntSet.union t u ;; 

Beachten Sie, dass Sie nicht explizit die Eingangsstruktur für Set.Make als OrderedType definieren; Typ Rückschluss wird die Arbeit für Sie erledigen. Alternativ können Sie die folgende Definition verwenden:

module IntOrder : Set.OrderedType = struct 
    type t = int 
    let compare = Pervasives.compare 
end 

module IntSet = Set.Make(IntOrder) 

Dies hat den Vorteil, dass Sie das gleiche Modul wiederverwenden ein Map instanziiert:

module IntMap = Map.Make(IntOrder) 

Sie verlieren einige Genericity sich mit der functors, weil Der Typ der Elemente ist festgelegt. Zum Beispiel können Sie keine Funktion definieren, die einen beliebigen Typ Set übernimmt und einige Operationen daran ausführt. (Zum Glück, das Set Modul selbst viele nützliche Operationen auf Set s erklärt.)

+1

"Sie können keine Funktion definieren, die ein beliebiges Set verwendet" Führen Sie das gleiche durch, indem Sie die Funktion in einem Funktor definieren, der Ihr spezifisches Set-Modul als Parameter verwendet. aber um es natürlich zu benutzen, müsste der Programmierer noch ein weiteres Modul mit diesem Funktor machen, also ist es weniger praktisch – newacct

+0

Richtig. Es ist Funktoren den ganzen Weg hinunter. –

9

Neben Chris Antwort kann es sinnvoll sein, zu sagen, dass einige Standard-Bibliotheksmodule haften bereits an die OrderedType Signatur. Zum Beispiel können Sie einfach tun:

module StringSet = Set.Make(String) ;;  (* sets of strings *) 
module Int64Set = Set.Make(Int64) ;;   (* sets of int64s *) 
module StringSetSet = Set.Make(StringSet) ;; (* sets of sets of strings *) 

Und so weiter.

Hier ist ein einfaches Anwendungsbeispiel für StringSet; Denken Sie daran, dass Sets funktionale Datenstrukturen sind. Wenn Sie also ein neues Element zu einem Set hinzufügen, wird ein neues Set zurückgegeben: