在父代签名中进一步完善嵌套模块的签名 [英] Further refining the signature of a nested module in the signature of the parent

查看:55
本文介绍了在父代签名中进一步完善嵌套模块的签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含嵌套模块的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆