2016-12-05 8 views
2

複数のモジュールからライブラリを作成する場合、必要なものすべてにアクセスできるようにライブラリのユーザ(外部インターフェイス)に適切な情報を隠す良い方法を見つけることができません内部インタフェースOCamlの外部と内部のインターフェイスと情報の隠蔽

具体的には、2つのモジュール(Files a.ml [i]とb.ml [i])があります。 Aでは、私はいくつかのタイプtを定義します。これは、ユーザ(外部インタフェース)から隠蔽したくない内部のものです。モジュールBで

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

、私はその後A.t秘密タイプを使用します。

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

Bのコンパイル単位はA.tの種類を知らないので、もちろんこれは、コンパイルされません。

私が知っているソリューションが、好きではない:

  1. BA
  2. コピーA.tの定義をモジュールといくつかのexternal cheat : `a -> `b = "%identity"
で型チェッカーをごまかすために機能 create_aを移動します

のタイプをBに知る他の方法は、この情報をライブラリのインターフェイスに漏らさないでください。

答えて

3

いつもと同じように、間接指定の追加層でこの問題を解決できます。

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 
を:あなたは、あなたがモジュール sigs.mlに一度それらを定義することができ、自分自身を繰り返し、二回モジュールの署名を書きたくない場合は、外部インターフェイスを指定しますモジュール Libを定義し、例えば、

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 

最後に、インストール手順でインターフェイス(.cmiファイル)、 をインストールしないようにして、ユーザーが抽象化をバイパスできないようにします。オアシスを使用している場合は、簡単です。すべてのモジュールをモジュールLibを除いて内部にします。つまり、InternalModulesフィールドで指定します。

+0

nice!さようなら 'pack'オプションです。 – lambdapower

関連する問題