3

ジェイソン・ヒッキーの本の演習12.5で誰か助けてくれませんか?

基本的に、問題は、実際に「含める」ことによる次の競合する問題をどのように回避するかです。ありがとう。

# module type XSig = sig 
type t 
val x : t 
end;; 
# module A : XSig = struct 
type t = int 
let x = 0 
end;; 
# module B : XSig = struct 
type t = int 
let x = 1 
end;; 
# module C = struct 
include A 
include B 
end;; 
4

1 に答える 1

9

質問が正確に何を言っているのかわかりませんが、コードスニペットに関しては、実行しようとしていることを解釈するためのさまざまな非常に異なる方法があります。

現在行っているのは、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型をマスクすることです。tB

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.tB.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 = ...構造のマニュアルページを参照してください。

于 2012-06-18T12:04:01.817 に答える