module - OCaml 模块类型和单独编译

标签 module ocaml

我正在阅读 OCaml lead designer's 1994 paper on modules, types, and separate compilation. (Norman Ramsey 中的 another question 向我指点)。我知道这篇论文讨论了 OCaml 当前模块类型/签名系统的起源。因此,作者建议对签名中的类型声明(以允许单独编译)以及 list 类型声明(为了表达性)进行不透明的解释。尝试整理我自己的一些示例来演示 OCaml 模块签名表示法试图解决的问题类型,我在两个文件中编写了以下代码:

在文件 ordering.ml (或.mli——我都试过了)(文件A):

module type ORDERING = sig
 type t
 val isLess : t -> t -> bool
end

并在文件 useOrdering.ml 中(文件 B):
open Ordering
module StringOrdering : ORDERING
  let main () =
    Printf.printf "%b" StringOrdering.isLess "a" "b"
  main ()

这个想法是期望编译器提示(在编译第二个文件时)模块 StringOrdering 上没有足够的类型信息可用。对 StringOrdering.isLess 进行类型检查应用程序(从而激发对 with type 语法的需求)。
但是,尽管文件 A 可以按预期编译,但文件 B 会导致 3.11.2 ocamlc提示语法错误。我知道签名是为了允许某人根据模块签名编写代码,而无需访问实现(模块结构)。

我承认我不确定语法:module A : B我在 this rather old paper on separate compilation 中遇到的但这让我想知道是否存在这样或类似的语法(不涉及仿函数)以允许某人仅基于模块类型编写代码,并在链接时提供实际模块结构,类似于如何使用 *.h*.c C/C++ 中的文件。如果没有这种能力,似乎模块类型/签名基本上是用于密封/隐藏模块内部或更明确的类型检查/注释,而不是用于单独/独立编译。

实际上,查看 OCaml manual section on modules and separate compilation似乎我与 C 编译单元的类比被打破了,因为 OCaml 手册将 OCaml 编译单元定义为 A.mlA.mli二重奏,而在 C/C++ 中 .h文件被粘贴到任何导入的编译单元 .c文件。

最佳答案

做这样的事情的正确方法是执行以下操作:

  • 在 ordering.mli 中写:
    (* This define the signature *)
    module type ORDERING = sig
      type t
      val isLess : t -> t -> bool
    end
    
    (* This define a module having ORDERING as signature *)
     module StringOrdering : ORDERING
    
  • 编译文件:ocamlc -c ordering.mli
  • 在另一个文件中,引用编译后的签名:
    open Ordering
    
    let main () =
      Printf.printf "%b" (StringOrdering.isLess "a" "b")
    
    let () = main ()
    

    编译文件时,您会收到预期的类型错误(即 stringOrdering.StringOrdering.t 不兼容)。如果要删除类型错误,应添加 with type t = stringStringOrdering 定义的约束在 ordering.mli .

  • 所以回答你的第二个问题:是的,在字节码模式下,编译器只需要知道你所依赖的接口(interface),你可以选择在链接时使用哪个实现。默认情况下, native 代码编译并非如此(因为模块间优化),但您可以禁用它。

    关于module - OCaml 模块类型和单独编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9843378/

    相关文章:

    maven-2 - Maven 支持属性继承吗?

    javascript - Web Workers 文件可以处理包含或模块吗?

    ocaml - 此函数是否使用尾部递归?

    variables - 如何处理 yacc/bison 中的变量引用(使用 ocaml)

    ocaml - 来自外部的参数化 GADT

    Python模块搜索路径

    types - mli 文件和 ml 文件中的签名之间的 OCaml 共享结构

    module - 如何从特定模块创建所有装饰函数的向量?

    types - 在调用函数和回调之间对齐多态变体类型

    ocaml - ML中有评估吗?