外部和内部接口&隐藏在OCaml中的信息

时间:2016-12-05 09:21:38

标签: module 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"
  3. 欺骗类型检查器

    是否有其他方法可以在A.t中了解B的类型,而不会将此信息泄露给图书馆的界面?

1 个答案:

答案 0 :(得分: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字段指定它们。

相关问题