2017-03-11 5 views
0

Gibt es einen Unterschied zwischen diesen beiden?Verwirrung über die Signatur eines Moduls in Ocaml

Ich weiß nicht, wer von ihnen sollte ich in meiner .mli Datei setzen

module Comparable : sig 
    type t 
    val compare : t -> t-> int 
end 

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

In real world ocaml Buch, sagen die Autoren, dass die Worte Schnittstelle, Unterschrift, Modultyp austauschbar verwendet werden können.

PS: Ich würde gerne den Titel der Frage zu einem besser geeigneten, irgendwelche Vorschläge ändern?

Antwort

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

definiert rewriten werden. Innerhalb einer Schnittstelle (z. B. einer .mli-Datei) ist es ein Versprechen, dass die Implementierung (.ml) dieselbe Modultypdefinition enthält.

module Comparable : sig 
    type t 
    val compare : t -> t-> int 
end 

in einer Schnittstelle ist ein Versprechen, ein Modul des gleichen Typs bereitzustellen. Dies entspricht

module Comparable : Comparable 

(vorausgesetzt, der Modultyp ist tatsächlich definiert).Es besagt, dass das entsprechende .ml ein Submodul mit dem Namen Comparable enthält.

Welche der zwei Sie in Sie setzen sollten .mli hängt davon ab, was Sie verspricht zu machen. Beide haben ihren Nutzen.

Modultypdefinitionen werden häufig in Schnittstellen gefunden, wenn sie als Argumente für Funktoren benötigt werden. In der Tat ist Ihr Modultyp Comparable gleich Map.OrderedType, der Typ des Arguments des Funktors Map.Make.

Ein Anwendungsfall von Submodulen wie oben ist bieten etwas, das als Argument für einen Funktor verwendet werden kann. Zum Beispiel könnte ein .mli wie folgt aussehen:

type stuff = ... 
val fancy : ... (* some operations on stuff *) 

module Comparable : Comparable with type t=stuff 

In dieser Form wäre es die Art stuff verwendbar als Schlüsseltyp einer Karte machen.

Das heißt, wenn Ihr Beispiel das vollständige Beispiel der realen Welt ist, dann vermute ich, dass Sie die Modultypdefinition wollen, nicht das Submodul: Das Submodul wäre nicht sehr nützlich; Sie haben keine Operation, um etwas vom Typ t zu konstruieren.

1

Sagen Sie, Ihre Datei heißt m.mli. Die erste Definition ist, was Sie verwenden, wenn Ihre entsprechende m.ml Datei ein Modul Comparable enthält. Das zweite ist, was Sie verwenden, um einen Modultyp zu deklarieren (nur der Typ eines Moduls, kein Modul). Im ersten Fall gibt es eine tatsächliche compare, die als M.Comparable.compare aufgerufen werden kann. Im zweiten Fall gibt es keine Vergleichsfunktion, nur eine Typdeklaration.

Es ist nicht möglich zu wissen, welche für Sie richtig ist. Sie ergeben beide Sinn.

1

.mli Datei ermöglicht eine .ml-Datei Zwang, siehe Beispiel unten:

/* foo.ml */ 
    let foo1 x y = x + y 
    let foo = foo1 

    /* foo.mli */ 
    val foo : int -> int -> int 

    /* main.ml */ 
    open Foo 
    let r = foo 4 5 
    /* let r = foo1 4 5 ;; */ 

ocamlbuild main.native nur kompiliert, wenn foo mit und wird mit foo1 Compiler fehlschlagen.

Nun, wenn Sie ein Modul definieren, können Sie entweder eine Erklärung verstecken, wenn dieses Modul mit:

module Comparable : sig 
    /* the exposed interface */ 
    end = struct 
    /* the computation */ 
    end 

Oder definieren eine Art für ein Modul:

module type Comparable = sig 
    /* the exposed interface */ 
    end 

Sie können die um diesen Typ später in Ihrem Code zu verwenden, um einige Module zu beschränken. Bei dem Beispiel oben gegeben (!! die .mli Datei löschen !!)

/* foo.ml */ 
    let foo1 x y = x + y 
    let foo = foo1 

    /* main.ml */ 
    module type T1 = sig 
    val foo : int -> int -> int 
    end 

    module F1 : T1 = Foo 
    let r = Foo.foo1 4 5 
    let r = F1.foo1 4 5 /* will fail because hiden by type T1 */ 
2

Ihr erstes ein Modul definiert Codefragment mit einer bestimmten Signatur definiert der zweite eine Signatur nicht direkt ein Modul. den Unterschied, Ihr Codebeispiel Um zu verstehen, kann einen Modultyp zu

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

module Comparable: COMPARABLE