假设我有一个模块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
编译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
我见过this similar post,但我不清楚其答案。
答案 0 :(得分:6)
文件a.ml
被隐式包装为模块A
,文件a.mli
被隐式包装为模块类型A
。
因此,以下方法可行
(* A.mli *)
val f : int -> int
(* A.ml *)
let f x = x + 1
您将以另一个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
您将以另一个f
的身份从另一个模块访问A.A.f
,并且模块A
除了(子)模块{{ 1}}。
标准ML的实现通常不会将文件的内容隐式包装为模块。
为完整起见,请注意,OCaml具有从模块“生成”模块类型的功能:
A_SIG