2016-12-05 38 views
2

從多個模塊創建庫時,我無法找到一種很好的方法,可以在訪問所需的所有內容的同時對庫(外部接口)的用戶執行正確的信息隱藏內部接口。隱藏在OCaml中的外部和內部接口和信息

更具體地說,我有兩個模塊(文件a.ml [i]和b.ml [i])。在A中,我定義了一些類型t,這是我不想從用戶(外部接口)隱藏的內部結構。

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

在模塊B,然後我想用祕密A.t

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

當然這並不編譯,因爲B的編譯單元不知道的A.t類型。

解決方案,我知道,但不喜歡:

  1. 移動功能create_a到模塊A
  2. 複製的A.t的定義B,並與一些external cheat : `a -> `b = "%identity"
欺騙類型檢查

有沒有其他方法可以知道BA.t的類型,而不會將此信息泄露到庫的界面?

回答

3

一如往常,間接的額外層可以解決這個問題。定義一個模塊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 

如果你不想重複自己,寫模塊簽名的兩倍,那麼你就可以一次一個模塊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 

最後,請確保在安裝步驟中未安裝接口(.cmi文件), ,以便用戶無法繞過抽象。如果你使用的是綠洲,那麼很簡單:只要讓你的所有模塊都在內部,除了模塊Lib,即用InternalModules字段指定它們。

+0

不錯!再見'包'選項。 – lambdapower