在父代签名中进一步完善嵌套模块的签名 [英] Further refining the signature of a nested module in the signature of the parent
问题描述
我有一个包含嵌套模块的ML文件.例如:
I have an ML file which contains a nested module. For example:
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
.
When writing an MLI for this ML, I wish not to expose M.h
, but I do wish to expose M.g
.
如下所示:
module type M_type = sig
val g : int -> int
end
module M : M_type
val j : int -> int
上面的ML和MLI组合无法编译.
The above combination of ML and MLI does not compile.
这个想法是我的嵌套模块M
包含一些我希望公开给父模块中其他函数的功能,而不是公开给父模块用户的一些功能.
The idea is that my nested module M
contains some functions that I do wish to expose to other functions in the parent module, but not to a user of the parent module.
有没有合法的方法来实现这一目标?如果不存在,那么实现签名缩小的最佳选择是什么?
Is there a legal way to achieve this? If there is none, what is the best alternative to achieve this kind of narrowing of the signature?
谢谢!
推荐答案
如果您仔细查看编译器错误:
If you look closely at the compiler error:
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
.
you will see that the compiler does not complain about the module M
, but about the module type M_type
.
实际上,两个模块类型的定义不匹配:
Indeed, the definition of the two module type does not match:
module type M_type = sig
val g : int -> int
val h : int -> int
end
与
module type M_type = sig
val g : int -> int
end
有很多方法可以解决此问题. 一种可能性是在不必要时不使用模块类型作为签名约束:
There are many ways to fix this problem. One possibility is to not use module type as signature constraint when unneccessary:
(* a.ml *)
module M = struct
let g n = n + 2
let h n = n + 3
end
类似地,mli文件可以写为
Similarly, the mli file can be written as
(*a.mli*)
module M : sig val g: int -> int end
另一种可能性是仅定义受约束的模块类型
Another possibility is to only define the constrained module type
(* 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文件:
with the associated mli file:
(*a.mli*)
module type M_type = sig val h: int -> int end
module M : sig val g: int -> int end
还可以为.ml
文件定义扩展模块类型EXT
:
It is also possible to define an extended module type EXT
for the .ml
file:
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
这篇关于在父代签名中进一步完善嵌套模块的签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!