2012-12-18 26 views
5

tôi đã xác định 2 module ZoneZones, Zones là danh sách các Zone, các chức năng nguyên nhân của Zones cần phải gọi chức năng của Zone:Một thiết kế của functors trong OCaml

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

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

Một tập tin nguyên tắc all.ml sử dụng ZonesMis mô-đun, mis.ml chứa các chức năng hoạt động trên cả hai Zone.tZones.t, ví dụ val Mis.make : Zone.t -> Zones.t.

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

Bây giờ, tôi muốn có thêm tùy chọn cho prop của Zone. Vì vậy, tôi xác định một giao diện PROPERTY và 2 mô-đun TypeFormula phù hợp với nó, để tôi có thể thực hiện các functors cho Zone và các địa chỉ khác trong đó ... prop: Property.t .... Bây giờ tôi có thể tưởng tượng một vài khả năng cho cái mới 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 } 

Mặc dù chữ ký của ZonesFunZoneFun là khác nhau giữa 3 lựa chọn, thực hiện điều này có thể đảm bảo ZoneXXX.tZonesXXX.t là chặt chẽ. Bây giờ một vấn đề lớn là làm thế nào để thay đổi Mis:

1) Nếu tôi thực hiện một functor MisFun: PROPERTY -> MIS và xây dựng ZoneXXXZonesXXX bên trong. Không thể biết MisXXX.Zone.t giống với Zone.t của all.ml hoặc MisXXX.Zones.t giống với Zones.t trong số all.ml.

2) Nếu tôi thực hiện một functor MisFun: Zone -> Zones -> MIS, nó không thể biết MisXXX.Zone.tMisXXX.Zones.t là mạch lạc.

Có ai biết cách giải quyết cả 1) và 2) không?

Trả lời

3

Trong tùy chọn (1), bạn có áp dụng ZoneFun bên trong ZonesFun?

Giả sử rằng, tôi nghĩ rằng sự lựa chọn là giữa (1) và (3)/(4) (có vẻ giống nhau). Lựa chọn nào phụ thuộc vào việc bạn có cần truy cập vào các mô-đun Zone được tạo bên ngoài ZoneFun (bạn cần (4)) hay không ((1) hoạt động tốt).

Cập nhật in reply to cập nhật:

Nếu tôi hiểu câu hỏi của bạn một cách chính xác, sau đó có vẻ như với tôi rằng Mis có để trở thành một functor là tốt. Hơn nữa, chữ ký của nó có thể chỉ định các loại như

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

nơi X là tham số functor.

(Btw, tôi vẫn thấy không có sự khác biệt giữa (3) và (4), ngoại trừ việc bạn đặt tên cho mô-đun phụ trợ.)

Cập nhật 2:

tôi đoán là bạn đang chạy vào một lỗi cũ và kém may mắn trong kiểm tra kiểu mô-đun OCaml (xem this discussion on the caml list). sau phải làm việc, nhưng không:

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} 

Bạn có thể buộc để làm cho nó hoạt động bằng cách đưa vào loại chú thích trong MakeMisc như sau:

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 

Nhưng rõ ràng, đó không phải là rất dễ chịu.

Tuy nhiên, cách phổ biến để chia sẻ trong ML, dù sao, là fibration, trong đó bạn đặt tên các loại hoặc mô-đun bạn muốn chia sẻ một cách trừu tượng trong chữ ký và tinh chỉnh chúng cho phù hợp. Sau đó, bạn có thể biến ZoneZones vào tham số bổ sung của Misc functor:

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

Trong Option (1), 'ZoneFun' được áp dụng trong 'ZonesFun'. – SoftTimur

+0

Tôi đã cập nhật OP, nó phức tạp hơn những gì chúng tôi nghĩ ... – SoftTimur

+1

Xem bản cập nhật thứ hai của tôi cho một câu trả lời rộng hơn. –

Các vấn đề liên quan