OCaml:集合之间的类型不兼容

时间:2013-07-31 16:47:24

标签: types ocaml set functor

我在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创建的,这意味着创建的两个集合的类型应该是相同的。

如果有人能对此提出任何想法,我将感激不尽。

1 个答案:

答案 0 :(得分:2)

尝试使用module S : module type of S(M)module S : Set.S with type elt = M.t and type t = S(M).tmodule S : Set.S with type elt = M.t的问题在于它不会限制类型S.t