2012-12-18 38 views
5

मैं 2 मॉड्यूल Zone और Zones परिभाषित किया है, ZonesZones के कारण कार्यों के Zone की एक सूची, Zone के कार्यों कॉल करने की आवश्यकता है और Mis मॉड्यूल, mis.ml में ऐसे कार्य शामिल हैं जो Zone.t और Zones.t दोनों पर काम करते हैं, उदाहरण के लिए val Mis.make : Zone.t -> Zones.tOCaml में functors का एक डिजाइन

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

अब, मैं Zone की prop के लिए अधिक विकल्प हैं करना चाहते हैं। इसलिए मैं एक इंटरफ़ेस PROPERTY और 2 मॉड्यूल Type और Formula से मेल खाता हूं, ताकि मैं 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 और ZoneFun के हस्ताक्षर 3 विकल्प के बीच अलग-अलग हैं, इसलिए ऐसा करना सुनिश्चित करें ZoneXXX.t और ZonesXXX.t सुसंगत हो गए हैं। अब एक बड़ी समस्या Mis परिवर्तित करने का तरीका है:

1) अगर मैं एक functor MisFun: PROPERTY -> MIS बनाने के लिए, और अंदर ZoneXXX और ZonesXXX निर्माण। यह MisXXX.Zone.tall.ml के समान नहीं है, या MisXXX.Zones.tall.ml के Zones.t के समान है।

2) यदि मैं एक मजेदार MisFun: Zone -> Zones -> MIS बनाता हूं, तो यह MisXXX.Zone.t और MisXXX.Zones.t सुसंगत नहीं हो सकता है।

क्या कोई जानता है कि दोनों को कैसे हल करें 1) और 2)?

उत्तर

3

विकल्प (1) में, क्या आप ZonesFun के अंदर लागू करते हैं?

मानते हैं कि, मुझे लगता है कि पसंद (1) और (3)/(4) (जो समान प्रतीत होता है) के बीच है। कौन सा चुनना है इस पर निर्भर करता है कि आपको ZoneFun (आपको आवश्यकता है (4)) के बाहर बनाए गए Zone मॉड्यूल तक पहुंचने में सक्षम होना चाहिए या नहीं ((1) ठीक काम करता है)। अद्यतन करने के लिए

उत्तर में अद्यतन:

अगर मैं आपके सवाल का सही ढंग से समझ है, तो मुझे लगता है Mis रूप में अच्छी तरह एक functor बनने के लिए है। इसके अलावा, उसके हस्ताक्षर की तरह

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

जहां X functor पैरामीटर है प्रकार निर्दिष्ट कर सकते।

(बीटीडब्ल्यू, मुझे अभी भी (3) और (4) के बीच कोई अंतर नहीं दिख रहा है, सिवाय इसके कि आप सहायक मॉड्यूल का नाम दें।)

अद्यतन 2:

मेरा अनुमान है (this discussion on the caml list देखें) है कि आप OCaml के मॉड्यूल प्रकार चेकर में एक पुराने और दुर्भाग्यपूर्ण बग में चल रहे हैं। निम्नलिखित चाहिए काम करने के लिए, लेकिन नहीं करता है:

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 

लेकिन जाहिर है, कि बहुत नहीं है सुहानी।

हालांकि, एमएल में साझा करने के लिए सामान्य तरीका कंपन है, जहां आप उन प्रकारों या मॉड्यूल का नाम देते हैं जिन्हें आप हस्ताक्षर में संक्षेप में साझा करना चाहते हैं और उन्हें तदनुसार परिशोधित करें।

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' अंदर लागू किया जाता है: तो फिर तुम Misc functor के अतिरिक्त पैरामीटर में Zone और Zones बदल सकते हैं। – SoftTimur

+0

मैंने ओपी को अपडेट किया है, यह हमने जो सोचा था उससे कहीं अधिक जटिल है ... – SoftTimur

+1

अधिक व्यापक उत्तर के लिए मेरा दूसरा अपडेट देखें। –