module - 隐藏在 OCaml 中的外部和内部接口(interface)和信息

标签 module ocaml

从多个模块创建库时,我找不到一种很好的方法来对库的用户(外部接口(interface))进行适当的信息隐藏,同时能够在内部接口(interface)上访问我需要的所有内容。

更具体地说,我有两个模块(文件 a.ml[i] 和 b.ml[i])。在 A 中,我定义了一些类型 t,这是我不想对用户隐藏的内部结构(外部接口(interface))。

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

然后在模块 B 中,我想使用 A.t 的 secret 类型.
module B : sig
  create_a : float -> A.t
end
module B = struct
  create_a x = x
end

这当然不编译,因为B的编译单元不知道A.t的类型.

我知道但不喜欢的解决方案:
  • 移动功能create_a转模块 A
  • 复制 A.t 的定义至B并用一些 external cheat : `a -> `b = "%identity" 欺骗类型检查器

  • 有没有其他方法可以知道 A.t 的类型?在 B没有将此信息泄漏到图书馆的界面?

    最佳答案

    与往常一样,额外的间接层可以解决这个问题。定义一个模块Lib这将指定一个外部接口(interface),例如,

    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
    

    最后,确保您没有安装接口(interface)(.cmi 文件),
    在您的安装步骤中,以便用户无法绕过您的抽象。如果您使用的是 oasis,那么这很简单:只需将所有模块设置为内部,模块 Lib 除外。 ,即用 InternalModules 指定它们 field 。

    关于module - 隐藏在 OCaml 中的外部和内部接口(interface)和信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40970844/

    相关文章:

    perl - directory/.pm 曾经是一个约定吗?它为什么存在?

    emacs - 确定在 emacs 中定义了哪个函数的模块?

    node.js - module.export 函数不返回结果

    types - 无法理解 OCaml trie 类型声明

    floating-point - OCaml - float 函数不起作用

    parsing - 一种解析 sexp 的优雅方式

    ocaml - OCaml 中的高阶类型(幻像类型子类型化)

    types - 包括模块、强制

    python - 为什么在 Python 中安装包和模块不一样?

    npm - 如何将节点模块导入到 slim 组件中