我在 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 创建的,这意味着创建的两个集合的类型应该相同。
如果有人能对此提出任何想法,我将不胜感激。
最佳答案
尝试使用module S:模块类型为S(M)
,或者module S:Set.S,类型为elt = M.t,类型t = S(M).t
。
module S : Set.S with type elt = M.t
的问题在于它不限制类型 S.t
关于types - OCaml:集合之间的类型不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17976247/