Module 使用'时放松类型检查;类型为';模块化构造

Module 使用'时放松类型检查;类型为';模块化构造,module,types,ocaml,signature,Module,Types,Ocaml,Signature,我定义了两种模块类型和两个模块 module type FOO = sig type e end module type BAR = sig type t end module Foo : FOO = struct type e = int end module Bar : BAR = struct type t = int end 然后我将函子定义为 module Fun (F:FOO) (B:BAR with type t = F.e) = struct type x = stri

我定义了两种模块类型和两个模块

module type FOO = sig type e end
module type BAR = sig type t end    
module Foo : FOO = struct type e = int end
module Bar : BAR = struct type t = int end
然后我将函子定义为

module Fun (F:FOO) (B:BAR with type t = F.e) = struct type x = string end
(这是一个玩具示例,请忽略以下事实:
F
B
未被函子使用)

现在,如果我定义模块

module Bla = Fun (Foo) (Bar)
我明白了

虽然
Bar.t
Foo.e
都被定义为
int
OCaml认为
Bar.t
Foo.e
是不同的。这就是打字系统工作的方式,一般认为这两种类型是不同的(C.F.最后一段)。 问题:有时我可能希望通过类型检查,因为就我而言,它们可以被视为相等。有没有办法放松一下


使用gasche关于消除强制的建议,上面的代码可以写成

module type FOO = sig type e end
module type BAR = sig type t end
module Foo = struct type e = int end
module Bar = struct type t = int end
module Fun (F : FOO with type e=int) (B : BAR with type t = int) = struct type x = F.e * B.t end
module Bla = Fun (Foo) (Bar)
这很好。奇怪的是,我

# let f x : Bla.x = (x,x);;
val f : Foo.e -> Bla.x = <fun>
#设fx:Bla.x=(x,x);;
val f:Foo.e->Bla.x=

问题:为什么推断
x
Foo.e
?它也可以是
Bar.t

问题在于如何定义
Foo
Bar
模块Foo:Foo=…
。通过在这里施加此签名,您可以“密封”模块并使类型抽象。它无法还原。您应该在这里删除
:FOO
强制,并在以后需要抽象时使用它。您还可以使用
模块Foo:(类型为e=int的Foo)=…

我不确定打印机如何在相同类型中进行选择,但在这种情况下,您可以通过显式注释函数参数使其打印不同的名称:

# let f (x:Bar.t) : Bla.x = (x,x);;
val f : Bar.t -> Bla.x = <fun>
#设f(x:Bar.t):Bla.x=(x,x);;
val f:Bar.t->Bla.x=

好的,很公平。我会让你尽可能晚一些。做这件事听起来不太好,但我的代码(上面是一个玩具示例)现在正在运行,所以我会接受它。谢谢
# let f (x:Bar.t) : Bla.x = (x,x);;
val f : Bar.t -> Bla.x = <fun>