OCaml の型の非互換性に問題があります。
まず、セットの順序を作成するファンクター SO、セットを作成するファンクター S、およびセットを操作するための便利な関数を含むモジュールを作成するファンクター SM を定義するファイル setBuilder.ml があります。
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 という別のファイルで、関数 foo が重要になるモジュール U を定義します。
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 で作成されているため、これが問題である理由です。つまり、作成された 2 つのセットのタイプは同じでなければなりません。
誰かがこれについて何か考えを提供できるなら、私は感謝します.