2016-12-05 2 views
2

Wenn ich eine Bibliothek aus mehreren Modulen erstelle, finde ich keine gute Möglichkeit, dem Benutzer der Bibliothek (externe Schnittstelle) korrekte Informationen zu verbergen, während ich auf alles zugreifen kann die interne Schnittstelle.Externe und interne Schnittstellen und Informationen in OCaml verbergen

Um genauer zu sein, habe ich zwei Module (Dateien a.ml [i] und b.ml [i]). In A definiere ich einen Typ t, dessen Inneres ich nicht vor dem Benutzer verbergen möchte (externe Schnittstelle).

module A : sig 
    type t 
end 
module A = struct 
    type t = float 
end 

In Modul B, ich will dann die Geheimnis Art von A.t verwenden.

module B : sig 
    create_a : float -> A.t 
end 
module B = struct 
    create_a x = x 
end 

Dies ist natürlich nicht kompiliert, da die Übersetzungseinheit von B nicht die Art von A.t nicht kennt.

Lösungen Ich weiß, aber nicht mag:

  1. Verschieben Sie die Funktion create_aA
  2. Kopieren Sie die Definition von A.t-B und betrügen den Typ-Checker mit einigen external cheat : `a -> `b = "%identity"
zum Modul

Gibt es eine andere Möglichkeit, den Typ A.t in B zu kennen, ohne diese Informationen an die Schnittstelle der Bibliothek zu verlieren?

Antwort

3

Wie immer kann eine zusätzliche Indirektionsebene dieses Problem lösen. Definieren Sie ein Modul Lib, die eine externe Schnittstelle angeben werden, zB

module Lib : sig 
module A : sig 
    type t 
    (* public interface *) 
end 
module B : sig 
    type t 
    (* public interface *) 
end = struct 
    module A = A 
    module B = B 
end 

Wenn Sie sich nicht wiederholen möchten und schreiben Modul Signaturen zweimal, dann können Sie sie einmal in einem Modul definieren sigs.ml:

module Sigs = struct 
    module type A = sig 
    type t 
    (* public interface *) 
    end 

    (* alternatively, you can move it into sigs_priv.ml *) 
    module type A_private = sig 
    include A 
    val create_a : float -> t 
    end 

    ... 
end 

Stellen Sie abschließend sicher, dass Sie während des Installationsschritts keine Schnittstellen (.cmi Dateien), installieren, damit Benutzer Ihre Abstraktion nicht umgehen können. Wenn Sie Oase verwenden, dann ist es einfach: Machen Sie alle Ihre Module intern, mit Ausnahme des Moduls Lib, d. H. Spezifizieren Sie sie mit InternalModules Feld.

+0

nett! Auf Wiedersehen 'Pack'-Option ist es. – lambdapower

Verwandte Themen