我有一个包含嵌套模块的ML文件。例如:
let f n = n + 1
module type M_type = sig
val g : int -> int
val h : int -> int
end
module M : M_type = struct
let g n = n + 2
let h n = n + 3
end
let j n = n |> M.h |> M.g |> f
为此ML编写MLI时,我希望不公开M.h
,但我希望公开M.g
。
如下:
module type M_type = sig
val g : int -> int
end
module M : M_type
val j : int -> int
ML和MLI的上述组合无法编译。
我的想法是我的嵌套模块M
包含一些我希望公开给父模块中的其他函数的函数,但不包含父模块的用户。
有没有合法的方法来实现这一目标?如果没有,那么实现这种签名缩小的最佳选择是什么?
谢谢!
答案 0 :(得分:6)
如果仔细查看编译器错误:
Module type declarations do not match:
module type M_type = sig val g : int -> int val h : int -> int end
does not match
module type M_type = sig val g : int -> int end
您将看到编译器不会抱怨模块M
,而是关于模块类型M_type
。
实际上,两种模块类型的定义不匹配:
module type M_type = sig
val g : int -> int
val h : int -> int
end
与
不兼容module type M_type = sig
val g : int -> int
end
有很多方法可以解决这个问题。 一种可能性是在不必要时不使用模块类型作为签名约束:
(* a.ml *)
module M = struct
let g n = n + 2
let h n = n + 3
end
同样,mli文件可以写成
(*a.mli*)
module M : sig val g: int -> int end
另一种可能性是仅定义受约束的模块类型
(* a.ml *)
module type M_type = sig val g: int -> int end
module M: sig include M_type val h: int -> int end =
(* Note that the signature constraint above is not necessary *)
struct
let g n = n + 2
let h n = n + 3
end
与相关的mli文件:
(*a.mli*)
module type M_type = sig val h: int -> int end
module M : sig val g: int -> int end
还可以为EXT
文件定义扩展模块类型.ml
:
module type M_type = sig val g: int -> int end
module type EXT = sig include M_type val h: int -> int end
module M: EXT = struct
let g n = n + 2
let h n = n + 3
end