假设我有一个模块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)
我看过这个类似的帖子,但我的回答并不清楚.
该文件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)