5

私は2つのモジュールを定義Zoneしました.ZonesZonesZoneZonesZone

module Zone = struct
 type t = 
 { ...
   prop: bool }
 ...
end

modules Zones = struct
  type t =
  | ZSbot
  | ZS of Zone.t list
  | ZStop
  ...
end

プリンシパル ファイルall.mlZonesMisモジュールを 使用し、とのmis.ml両方で機能する関数を含みます。Zone.tZones.tval Mis.make : Zone.t -> Zones.t

open Zones
open Mis
type t = { zs: Zones.t }
...
Mis.make z

propここで、 of のオプションを増やしたいと思いますZone。そこで、インターフェースPROPERTYと 2 つのモジュールを定義し、それTypeFormula一致させて、Zoneおよびその他の場所のファンクターを作成できるようにし... prop: Property.t ...ます。これで、新しい のいくつかの可能性を想像できますall.ml

(* 1 *)
open Zones
module ZonesType = ZonesFun(Type)
module ZonesFormula = ZonesFun(Formula)
type t = { zstype: ZonesType.t; zsformula: ZonesFormula }

(* 3 *)
open Zones
module ZonesType = ZonesFun(ZoneFun(Type))
module ZonesFormula = ZonesFun(ZoneFun(Formula))
type t = { zstype: ZonesType.t; zsformula: ZonesFormula }

(* 4 *)
open Zones
module ZoneType = ZoneFun(Type)
module ZoneFormula = ZoneFun(Formula)
module ZonesType = ZonesFun(ZoneType)
module ZonesFormula = ZonesFun(ZoneFormula)
type t = { zstype: ZonesType.t; zsformula: ZonesFormula }

ZonesFunとのシグネチャはZoneFun3 つのオプション間で異なりますが、この実装は確実ZoneXXX.tZonesXXX.t一貫性があります。ここで大きな問題の 1 つは、次のように変更する方法Misです。

1) functorを作成し、内部MisFun: PROPERTY -> MISに and を構築するZoneXXXとします。の と同じか、のと同じかを知ることはできZonesXXXません。MisXXX.Zone.tZone.tall.mlMisXXX.Zones.tZones.tall.ml

2) functor を作成するとMisFun: Zone -> Zones -> MIS、それは知ることができず、一貫性がMisXXX.Zone.tあります。MisXXX.Zones.t

1)と2)の両方を解決する方法を知っている人はいますか?

4

1 に答える 1

3

選択肢(1)では、ZoneFun内に適用しZonesFunますか?

と仮定すると、(1)と(3)/(4)のどちらかが選択されると思います(どちらも同じようです)。どちらを選択するかは、作成したZoneモジュールに外部からアクセスできるようにする必要があるかZoneFun((4) が必要)、そうでないか ((1) が正常に機能するか) によって異なります。

更新に応答して更新:

あなたの質問を正しく理解していれば、それもMisファンクターにならなければならないように思えます。さらに、その署名は次のようなタイプを指定できます

val make: ZoneFun(X).t -> ZonesFun(X).t

Xfunctor パラメータです。

(ちなみに、補助モジュールに名前を付けることを除いて、(3) と (4) の間に違いはまだありません。)

更新 2:

私の推測では、あなたは OCaml のモジュール タイプ チェッカーの古くて残念なバグに遭遇しているのではないでしょうか ( caml リストのこの議論を参照してください)。以下は機能するはずですが、機能しません。

module type PROP = sig type t end
module type ZONE = sig type t end
module MakeZone (P : PROP) = struct type t = {p : P.t} end
module MakeZones (Z : ZONE) = struct type t = ZS of Z.t list end

module MakeMisc (P : PROP) :
sig
  val make : MakeZone(P).t -> MakeZones(MakeZone(P)).t
end =
struct
  module Zone = MakeZone(P)
  module Zones = MakeZones(Zone)
  let make z = Zones.ZS [z]
end

module Type = struct type t = T end
module Formula = struct type t = F end
module ZoneType = MakeZone(Type)
module ZoneFormula = MakeZone(Formula)
module ZonesType = MakeZones(ZoneType)
module ZonesFormula = MakeZones(ZoneFormula)
module MiscType = MakeMisc(Type)
module MiscFormula = MakeMisc(Formula)
let zst = MiscType.make {ZoneType.p = Type.T}
let zsf = MiscFormula.make {ZoneFormula.p = Formula.F}

MakeMisc次のように型注釈を挿入することで、強制的に機能させることができます。

module MakeMisc (P : PROP) :
sig
  val make : MakeZone(P).t -> MakeZones(MakeZone(P)).t
end =
struct
  module Zone : sig type t = MakeZone(P).t end = MakeZone(P)
  module Zones :
    sig type t = MakeZones(MakeZone(P)).t = ZS of MakeZone(P).t list end =
    MakeZones(MakeZone(P))
  let make z = Zones.ZS [z]
end

しかし、明らかに、それはあまり楽しいことではありません。

ただし、とにかく、ML で共有を表現する一般的な方法はfibrationによるものです。これは、共有したい型またはモジュールを署名で抽象的に指定し、それに応じてそれらを改良するものです。次に、ファンクターの追加パラメーターに変換Zoneできます。ZonesMisc

module type PROP = sig type t end
module type ZONE = sig type prop type t = {p : prop} end
module type ZONES = sig type zone type t = ZS of zone list end
module MakeZone (P : PROP) = struct type prop = P.t type t = {p : prop} end
module MakeZones (Z : ZONE) = struct type zone = Z.t type t = ZS of zone list end

module MakeMisc
  (P : PROP) (Z : ZONE with type prop = P.t) (Zs : ZONES with type zone = Z.t) :
sig
  val make : Z.t -> Zs.t
end =
struct
  let make z = Zs.ZS [z]
end

module Type = struct type t = T end
module Formula = struct type t = F end
module ZoneType = MakeZone(Type)
module ZoneFormula = MakeZone(Formula)
module ZonesType = MakeZones(ZoneType)
module ZonesFormula = MakeZones(ZoneFormula)
module MiscType = MakeMisc(Type)(ZoneType)(ZonesType)
module MiscFormula = MakeMisc(Formula)(ZoneFormula)(ZonesFormula)
let zst = MiscType.make {ZoneType.p = Type.T}
let zsf = MiscFormula.make {ZoneFormula.p = Formula.F}
于 2012-12-18T17:14:17.750 に答える