2010-10-28 5 views
6
module <name> = 
    struct 
    .. 
    end;; 


module type <name> = 
    struct (* should have been sig *) 
     .. 
end;; 
+3

Haben Sie versucht, Ihren 'Modultyp Name = struct ... end' zu kompilieren, bevor Sie gefragt werden? –

+0

Ich wollte nur ein Beispiel illustrieren. Ich arbeitete an einem großen Modul und erkannte, dass ich die Leute nicht von der eigentlichen Frage ablenken wollte. –

Antwort

7

Die erste deklariert ein Modul und die zweite deklariert einen Modultyp (aka eine Signatur). Ein Modultyp enthält die Deklarationen type und val, während ein Modul Definitionen enthalten kann (z. B. let Bindungen). Sie können eine Signatur verwenden, um den Typ eines Moduls zu beschränken, ähnlich wie bei einer Funktion. Zum Beispiel

module type T = sig 
    val f : int -> int 
end 

module M : T = struct 
    let f x = x + 1 
    let g x = 2 * x 
end 

Jetzt haben wir

# M.f 0 ;; 
- : int = 1 
# M.g 0 ;; 
Error: Unbound value M.g 

M.g ungebunden ist, weil es durch die Unterschrift T versteckt ist.

Eine andere gängige Methode, Modultypen zu verwenden, sind Argumente und Rückgabewerte von Funktoren. Zum Beispiel nimmt die Map.Make Funktors in the standard library ein Modul mit Unterschrift Map.OrderedType und schafft ein Modul mit Unterschrift Map.S

P.S. Beachten Sie, dass in der Frage ein Fehler vorliegt. Ein Modultyp wird unter Verwendung erklärt

module type <name> = sig 
    ... 
end 
0

Modultyp ein Modul beschreiben. Es ist das gleiche wie der Unterschied zwischen .ml und .mli

3

A Struktur (geschrieben struct … end) ist ein Bündel von Definitionen. Jedes Objekt in der Sprache kann in einem Modul definiert werden: Kernwerte (let x = 2 + 2), Typen (type t = int), Module (module Empty = struct end), Signaturen (module type EMPTY = sig end) usw. Module sind eine Verallgemeinerung von Strukturen: eine Struktur ist ein Modul, und so ist ein Funktor (denken Sie an es als eine Funktion, die ein Modul als Argument nimmt und ein neues Modul zurückgibt). Module sind wie Kernwerte, leben aber eine Ebene darüber: Ein Modul kann alles enthalten, während ein Kernwert nur andere Kernwerte enthalten kann¹.

A Unterschrift (geschrieben) ist ein Bündel von Spezifikationen (in einigen Sprachen verwenden den Begriff Erklärung). Jedes Objekt in der Sprache kann in einem Modul angegeben werden: Kernwerte (val x : int), Typen (type t = int), Module (module Empty : sig end), Signaturen (module type EMPTY = sig end) usw. Modultypen Signaturen verallgemeinern: Ein Modultyp spezifiziert ein Modul, und Ein Modultyp, der zufälligerweise eine Struktur angibt, wird als Signatur bezeichnet. Modultypen sind für Module, welche gewöhnlichen Typen Kernwerte sind.

Kompilierungseinheiten (.ml Dateien) sind Strukturen. Schnittstellen (.mli Dateien) sind Signaturen.

Also module Foo = struct … end definiert ein Modul namens Foo, die eine Struktur ist. Dies ist analog zu let foo = (1, "a"), die einen Wert definiert, der foo genannt wird, der zufällig ein Paar ist. Und module type FOO = sig … end (Hinweis: sig, nicht struct) definiert einen Modultyp namens FOO, die eine Signatur ist.Dies ist analog zu type foo = int * string, das einen Typ namens foo definiert, der zufällig ein Produkttyp ist.

¹ Dies ist in der Tat nicht mehr wahr, da OCaml 3.12 erstklassige Module eingeführt hat, aber es ist nahe genug für eine einführende Präsentation.

Verwandte Themen