我在 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 创建的,这意味着创建的两个集合的类型应该相同。
如果有人可以对此提供任何想法,我将不胜感激。