参数化模块类型

时间:2018-02-19 19:19:55

标签: ocaml

我正在尝试构建一个彼此依赖的模块类型的层次结构。在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中表达它?

3 个答案:

答案 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;;