2

我在 OCaml 中遇到类型不兼容的问题。

首先,我有一个文件 setBuilder.ml,我在其中定义了一个为集合创建顺序的仿函数 SO、一个创建集合的仿函数 S,以及一个创建包含用于处理集合的有用函数的模块的仿函数 SM:

module SO (M: sig type t end)
  = struct
    type t = M.t
    let compare = Pervasives.compare
  end

module S (P: sig type t end): Set.S with type elt = P.t
  = Set.Make (SO (P))

module SM (M: sig type t end): 
sig
  type t = M.t
  module S: Set.S with type elt = t
  type set = S.t
  ...
end
= struct
  module S = S (M)
  ...
end

(在这种情况下,我习惯于将这样的 3 个模块组合成 1 个递归模块,但似乎 OCaml 不允许您在参数被排除时(即,当它是函子时)创建递归模块)。

然后在另一个名为 module_U.ml 的文件中,我定义了一个模块 U,其中函数 foo 很重要:

module U (M: sig type t end):
sig
  module S : Set.S with type elt = M.t
  type elt = M.t
  type eltSet = S.t
  val foo: eltSet -> eltSet -> bool
end
= struct 
  module S = S (M)
  let foo s1 s2 = 
  ...
end

在我的 main.ml 中,我最终定义了一个包含我将使用的类型的模块,

module T : 
sig 
  type t=int
end 
= struct 
  type t=int
end 

然后我实例化模块 SM 并获得它的集合 S:

module SM = SM (T)  
module IntSet = SM.S 

然后我实例化模块 U 并尝试使用它的函数 foo:

module U = U (T)
let bar (s1:IntSet.t) (s2:IntSet.t) : bool = 
  U.foo s1 s2

但我收到错误消息

File "main.ml", line 303, characters 38-39  (which corresponds to s1, in U.foo s1 s2):
Error: This expression has type IntSet.t = setBuilder.SM(T).S.t
       but an expression was expected of type
         U.eltSet = module_U.U(T).S.t

我不明白为什么这是一个问题,因为 U 和 SM 模块都是使用相同的模块 T 创建的,这意味着创建的两个集合的类型应该相同。

如果有人可以对此提供任何想法,我将不胜感激。

4

1 回答 1

2

尝试使用module S : module type of S(M),或替代module S : Set.S with type elt = M.t and type t = S(M).t。问题module S : Set.S with type elt = M.t在于它不限制类型 St

于 2013-07-31T21:00:41.200 回答