質問が正確に何を言っているのかわかりませんが、コードスニペットに関しては、実行しようとしていることを解釈するためのさまざまな非常に異なる方法があります。
現在行っているのは、2つの抽象的な互換性のない署名の下で封印A
し、B
それらをモジュール内で混合しようとして、名前が競合することだけです。
名前の競合を避けたいだけかもしれません。もちろん、最も簡単な解決策は、タイプA.t
との両方に同じ名前を使用しないことB.t
です。次に、「含めることはできませんB
」:
module C = struct
include A
let x_b = B.x
end
より良い解決策は、署名の代わりにOCaml 3.12の破壊的な置換を使用して、モジュールからwith type t := foo
型をマスクすることです。t
B
module C = struct
include A
type u = B.t (* rename B.t into 'u' to avoid name conflict *)
include (B : XSig with type t := u) (* replaces 't' by 'u' *)
end
モジュールのタイプと互換性が必要な場合もありA
ますB
。この場合、抽象型でそれらを封印してはなりません。
module type XSig = sig
type t
val x : t
end
module A = struct
type t = int
let x = 0
end
(* if you want to check that A can be sealed by XSig, do it here,
outside the main declaration *)
let _ = (module A : XSig)
module B = struct
type t = int
let x = 1
end
module C = struct
include (A : XSig with type t := int)
include (B : XSig with type t := int)
end
(* module C : sig
val x = int
end *)
この例では、両方のタイプA.t
とB.t
が破壊的な置換によって削除されてい:=
ます。C
モジュールにタイプを持たせたい場合はt
、次のいずれかを記述できます。
module C = struct
type t = int
include (A : XSig with type t := t)
include (B : XSig with type t := t)
end
または、非破壊置換を使用する(タイプ定義を削除する代わりに変更する):
module C = struct
include (A : XSig with type t = int)
include (B : XSig with type t := t)
end
詳細については、破壊的な置換のマニュアルページをtype type t := ...
参照してください。比較については、従来のwith type t = ...
構造のマニュアルページを参照してください。