我正在尝试构建一个彼此依赖的模块类型的层次结构。在Coq我可以这样写:
Module Type Foo.
Parameter t:Type.
End Foo.
Module Type Bar1 (T:Foo).
Parameter f1: T.t -> T.t.
End Bar1.
Module Type Bar2 (T:Foo).
Parameter f2: T.t -> T.t.
End Bar2.
Module Ex (F:Foo) (B1: Bar1 F) (B2:Bar2 F).
End Ex.
我如何在OCaml中表达它?
答案 0 :(得分:5)
不幸的是,Ocaml不直接支持参数化模块类型。但是,您可以通过在其周围包装参数化模块来模拟它们:
module type Foo =
sig
type t
end
module Bar (X : Foo) =
struct
module type T =
sig
val f : X.t -> X.t
end
end
module Ex (F : Foo) (B : Bar(F).T) = ...
有点笨拙,但效果相同。
答案 1 :(得分:2)
模块类型不带参数。但是,这种特殊模式可以用with type
表示:
module type FOO = sig
type t
end
module type BAR1 = sig
type t
val f1 : t -> t
end
module type BAR2 = sig
type t
val f2 : t -> t
end
module Ex (F:FOO) (B1 : BAR1 with type t = F.t) (B1 : BAR2 with type t = F.t) = struct
end
答案 2 :(得分:2)
要详细说明gsg的答案,如果您有更复杂的Foo
模块类型,则可以使用with module
代替with type
,并且两者都有模块规范Bar
类型,如下例所示:
module type Foo =
sig
type t
end
module type Bar1 = sig
module F: Foo
val f1: F.t -> F.t
end
module type Bar2 = sig
module F: Foo
val f2: F.t -> F.t
end
module Ex (F: Foo) (B1: Bar1 with module F = F) (B2: Bar2 with module F = F) =
struct
let f3 x = B2.f2 (B1.f1 x)
end
module Bar1_impl (F: Foo): Bar1 with module F = F = struct
module F = F
let f1 x = x
end
module Bar2_impl (F: Foo): Bar2 with module F = F = struct
module F = F
let f2 x = x
end
module F: Foo with type t = int = struct type t = int end
module M = Ex(F)(Bar1_impl(F))(Bar2_impl(F))
let x = M.f3 0;;