OCaml在实现中重复整个签名

Mat*_*s17 3 ocaml module sml

假设我有一个模块A,具有以下接口和实现文件:

(* a.mli *)
module type A_SIG =
sig
    val f: int -> int
    ...
end

(* a.ml *)
module A : A_SIG =
struct
    let f x = x + 1
    ...
end
Run Code Online (Sandbox Code Playgroud)

编译a.mli后跟a.ml失败,错误Unbound module type A_SIG.复制实现文件中的整个签名可以修复它.

为什么会这样?似乎以下工作在SML中:

(* a.sig *)
signature A_SIG =
sig
    val f: int -> int
    ...
end

(* a.sml *)
structure A : A_SIG =
struct
   fun f x = x+1
   ...
end
Run Code Online (Sandbox Code Playgroud)

我看过这个类似的帖子,但我的回答并不清楚.

tbr*_*brk 6

该文件a.ml隐式包装为模块A,文件a.mli隐式包装为模块类型A.

以下是有效的

(* A.mli *)
val f : int -> int

(* A.ml *)
let f x = x + 1
Run Code Online (Sandbox Code Playgroud)

你可以f从另一个模块访问A.f.

或者,如果你真的想要子模块,你可以写

(* a.mli *)
module type A_SIG =
sig
    val f: int -> int
end

module A : A_SIG

(* a.ml *)
module type A_SIG =
sig
    val f: int -> int
end

module A : A_SIG =
struct
    let f x = x + 1
end
Run Code Online (Sandbox Code Playgroud)

并且您f将从另一个模块访问,除了(子)模块之外,A.A.f模块A还将包含签名.A_SIGA

标准ML的实现通常不会隐式地将文件的内容包装为模块.

为了完整起见,请注意OCaml具有从模块"生成"模块类型的功能:

(* a.mli *)
module type A_SIG =
sig
    val f: int -> int
end

module A : A_SIG

(* a.ml *)
module A =
struct
    let f x = x + 1
end

module type A_SIG = module type of A
Run Code Online (Sandbox Code Playgroud)