如何接收从函子构建的类型作为 OCaml 中函数的参数?

How to receive types built from functors as argument to functions in OCaml?

我正在研究函子,我试图接收一个 Module.t 作为参数,其中 Module 是函子调用 SomeFunctor(sig type t = int end) 的结果,但我收到 Unbound type constructor FooInt.t

这是代码

module type Foo_S = sig
  type t
end

module type Foo = sig
  type t
  val id : t -> t
end

module FooExtend(Arg : Foo_S) : (Foo with type t := Arg.t) = struct
  let id a = a
end

module FooInt = FooExtend(Int)
module FooString = FooExtend(String)

let () =
  assert (FooInt.id 1 = 1);
  assert (FooString.id "x" = "x")

module FooSimple = struct type t = int end

let foo (x : FooInt.t) = (* This doens't compile: Unbound type constructor FooInt.t *)
  FooInt.id x

let foo' (x : FooSimple.t) = (* This works fine *)
  FooInt.id x

需要进行两处更改,1) type t 需要在模块中定义,2) 不要使用破坏性替换:

module FooExtend(Arg : Foo_S) : (Foo with type t = Arg.t) = struct
  type t = Arg.t
  let id a = a
end

问题是破坏性替换 (type t := Arg.t) 将每次出现的 t 替换为 Arg.t。相反,您想使用“共享约束”(type t = Arg.t).

来指定类型相等性

注意两者之间生成的模块签名的差异:

module FooExtend(Arg : Foo_S) : (Foo with type t := Arg.t) = struct
  type t = Arg.t
  let id a = a
end

module FooExtend : functor (Arg : Foo_S) -> sig 
  val id : Arg.t -> Arg.t
end
module FooExtend(Arg : Foo_S) : (Foo with type t = Arg.t) = struct
  type t = Arg.t
  let id a = a
end

module FooExtend : functor (Arg : Foo_S) -> sig
    type t = Arg.t
    val id : t -> t
end