2012-12-18 39 views
5

我已經定義了2個模塊ZoneZonesZones是的Zones事業功能的Zone列表,需要調用的Zone功能:函子OCaml中一個設計

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

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

一個原則文件all.ml使用ZonesMis模塊,mis.ml包含在Zone.tZones.t上工作的功能,例如val Mis.make : Zone.t -> Zones.t。現在

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

,我想擁有的Zoneprop更多的選擇。所以我定義了一個接口PROPERTY和兩個模塊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 } 

雖然ZonesFunZoneFun簽名是3個選項中的不同,該實施可以確保ZoneXXX.tZonesXXX.t是一致的。現在一個很大的問題是如何改變Mis

1)如果我做一個仿函數MisFun: PROPERTY -> MIS,並建立ZoneXXXZonesXXX內。不知道MisXXX.Zone.tall.mlZone.t相同,或者MisXXX.Zones.tall.mlZones.t相同。 2)如果我做了一個仿函數MisFun: Zone -> Zones -> MIS,它不知道MisXXX.Zone.tMisXXX.Zones.t是連貫的。

有沒有人知道如何解決1)和2)?

回答

3

在選項(1)中,您是否在ZonesFun中應用ZoneFun

假設我認爲選擇是在(1)和(3)/(4)之間(它們似乎是相同的)。選擇哪一個取決於您是否需要能夠訪問在ZoneFun(您需要(4))或不((1)正常工作)之外創建的Zone模塊。在回答

Update更新:

如果我正確理解你的問題,然後我看來,Mis有可能成爲一個函子爲好。此外,其簽名可指定類型如

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

其中X是仿函數參數。 (順便說一下,我還是看到(3)和(4)之間沒有區別,除了你指定了輔助模塊。)

更新2:

我的猜測是,你正在運行到一個古老而又不幸的錯誤OCaml中的模塊類型檢查(見this discussion on the caml list)。下面應該以工作,但不會:

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,其中您要在簽名中抽象地分享類型或模塊,並相應地對其進行細化。這樣就可以開啓和ZoneZonesMisc算符的附加參數:

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} 
+0

在備選方案(1),'ZoneFun'被內部'ZonesFun'施加。 – SoftTimur

+0

我已經更新了OP,它比我們想象的更復雜... – SoftTimur

+1

查看我的第二次更新以獲得更全面的答案。 –