是否可以在没有中间模块的情况下打开或使用仿函数?例如,假设我们有以下模块和仿函数:
module type FOO = sig
val foo : int -> int
end
module Foo1 : FOO = struct
let foo x = x+1
end
module Foo2 : FOO = struct
let foo x = x+2
end
module Bar(Foo : FOO) = struct
open Foo
let apply x = foo x
end
如果我们尝试
let _ = Bar(Foo1).apply 1
我们收到错误
Error: Parse error: currified constructor
当然,我们可以用
来实现这一目标let _ =
let module Bar' = Bar(Foo1) in
Bar'.apply 1
但它有点冗长。或者,如果我们定义一个使用仿函数的模块
module Buz(Foo : FOO) = struct
open Bar(Foo)
let buz x = apply x
end
我们收到错误
Error: This module is not a structure; it has type
functor (Foo : FOO) -> sig val apply : int -> int end
同样,我们可以用
解决这个问题module Buz(Foo : FOO) = struct
module M = Bar(Foo)
open M
let buz x = apply x
end
但它更冗长。另外,我们在M
中定义了一个新模块Buz
,它会污染命名空间
module Buz :
functor (Foo : FOO) ->
sig module M : sig val apply : int -> int end val buz : int -> int end
真的,我只想Buz
加入buz
。
基本上,我在问我是否缺少某种语法或技巧,让我们写下Bar(Foo1).apply
或open Bar(Foo1)
之类的内容。
答案 0 :(得分:3)
如果您正在访问类型,模块类型或类类型,则可以跳过仿函数的实例化。换句话说,它只能在内部类型表达式中。例如:
module type T = sig type t end
module Pair (T : T) = struct type t = T.t * T.t end
module Int = struct type t = int end
type int_pair = Pair(Int).t
关于你问题的第二部分,那么如果你真的想“想要Buz包含buz。”那么你应该使用include
:
module Buz(Foo : FOO) = struct
include Bar(Foo)
let buz x = apply x
end
open
和include
声明之间存在差异。 open X
不会添加X
中的任何定义,只需将其添加到搜索路径中即可。 include X
只会将所有定义从X
复制粘贴到包含它的位置。
如果您只想在模块中使用buz
,那么您可以使用模块签名隐藏它:
module type Buz = sig val buz : int -> int end
module Buz(Foo : FOO) : Buz = struct
include Bar(Foo)
let buz = apply
end