首页 > 解决方案 > OCaml 在实现中重复整个签名

问题描述

假设我有一个模块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.mlia.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

我看过这个类似的帖子,但我不清楚它的答案。

标签: moduleocamlsml

解决方案


文件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从另一个模块访问,并且除了 (sub)module 之外,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

推荐阅读