2009-03-21 15 views
9

मैं ओकैम में एक इंटरफ़ेस अनुकरण करने का प्रयास कर रहा हूं और "प्रकार" निर्माण का उपयोग कर रहा हूं। मैं दो प्रकार के होते हैं:विशिष्टता के विभिन्न स्तरों के साथ ओकैमल प्रकार

type fooSansBar = {a: string; b: int};; 
type fooConBar = {a:string; b:int; bar:char};; 

... और एक विशेष fooSansBar परिभाषित करना चाहते हैं:

let fsb = {a="a"; b=3};; 

... लेकिन बताया गया है कि बार क्षेत्र परिभाषित नहीं है। इससे, ऐसा लगता है कि, fooSansBar के हस्ताक्षर से मेल खाने वाले मानों के विपरीत, सिस्टम का मानना ​​है कि मैं fooConBar बनाने की कोशिश कर रहा हूं। क्या उपरोक्त परिभाषित दो प्रकार मौजूद हैं तो क्या fooSansBar बनाना संभव है?

इसके अतिरिक्त (क्योंकि मैं OCaml के लिए नया हूँ) वहाँ एक बेहतर तरीका है एक अंतरफलक अनुकरण करने के लिए है?

उत्तर

3

दूसरे प्रकार ए और बी को पुनर्परिभाषित, प्रभावी रूप से, पहले छुपा है, इसीलिए उसे किसी भी अधिक का निर्माण नहीं किया जा सकता है। आप इन प्रकारों को विभिन्न मॉड्यूल में परिभाषित कर सकते हैं, लेकिन यह ए और बी के लिए एक अलग नाम का उपयोग करने जैसा ही होगा।

इन निर्माणों केवल आप एक और इंटरफ़ेस की "प्राप्त" करने की कोशिश नहीं करते हैं, लेकिन सिर्फ इसे लागू किया जा सकता है।

आप OCaml में इन वस्तु उन्मुख अवधारणाओं का उपयोग करना चाहते हैं, तो आप अपनी समस्या का, मॉड्यूल सिस्टम के आधार पर वस्तु प्रणाली को देखो सकता है, या,। वैकल्पिक रूप से, आप अपनी समस्या को कार्यात्मक तरीके से हल करने का प्रयास कर सकते हैं। आप कौनसी समस्याएं हल करने की कोशिश कर रहे हैं?

9

OCaml में, रिकॉर्ड प्रकार में फ़ील्ड नाम, अद्वितीय होना चाहिए ताकि दो प्रकार आपके द्वारा निर्धारित एक साथ साथ नहीं रह सकते। कैमल एकमात्र भाषा है जिसे मैं इस संपत्ति के साथ जानता हूं।

क्योंकि दूसरी परिभाषा पहले छुपाती है, जब संकलक ए और बी फ़ील्ड देखता है तो यह उम्मीद करता है कि वे fooConBar प्रकार से संबंधित हैं और इसलिए लापता बार फ़ील्ड की शिकायतें हैं।

यदि आप एक इंटरफ़ेस अनुकरण करने की कोशिश कर रहे हैं, तो Caml में इसे करने का सही कार्यात्मक तरीका module type को परिभाषित करना है।

module type FOO_CON_BAR = sig 
    val a : string 
    val b : int 
    val bar : char 
end 

और एक उदाहरण:

module Example = struct 
    let a = "hello" 
    let b = 99 
    let c = '\n' 
end 
मॉड्यूल और मॉड्यूल प्रकार आप भी subtyping पाने के साथ

; वस्तुओं का सहारा लेने की कोई ज़रूरत नहीं है।

पीएस मेरा कैमल जंगली है; वाक्यविन्यास बंद हो सकता है।

4

ओकैम में कई संभावित समाधान हैं जो आप दिए गए कोड का उपयोग कर रहे हैं। सरल दो प्रकार के गठबंधन करने के लिए है: (! और उनके प्रकारों का अनुमान लगाया तो एक प्रकार की घोषणा करने की जरूरत नहीं है हो सकता है)

type fooBar = { a: string; b: int; bar: char option } 

एक अन्य समाधान है क्योंकि वस्तुओं subtyping समर्थन वस्तुओं के साथ रिकॉर्ड को बदलने के लिए है:

# let fsb = object 
    method a = "a" 
    method b = 3 
    end;; 
val fsb : < a : string; b : int > = <obj> 

# fsb#a, fsb#b;; 
- : string * int = ("a", 3) 
1

OCaml में, यह क्षेत्र में एक ही दायरे में मौजूद सेट अन्तर्विभाजक के साथ दो रिकॉर्ड प्रकारों के लिए संभव नहीं है।

तुम सच में क्षेत्र सेट अन्तर्विभाजक साथ रिकॉर्ड प्रकार का उपयोग करने की जरूरत है, तो आप इस प्रतिबंध के आसपास अपनी समर्पित मॉड्यूल के भीतर प्रकार बंद करके काम कर सकते हैं:

module FooSansBar = struct type t = {a:string; b:int} end 
module FooConBar = struct type t = {a:string; b:int; bar:char} end 

तो फिर तुम इन प्रकार की तरह के उदाहरण का निर्माण कर सकते इसलिए:

let fsb = {FooSansBar.a="a"; b=3} 
let fcb = {FooConBar.a="a"; b=4; bar='c'} 

इन उदाहरणों निम्नलिखित प्रकार है:

fsb : FooSansBar.t 
fcb : FooConBar.t 
2

ओकैमल इंटरफेस को लागू करने के दो तरीके प्रदान करता है। एक, जैसा कि पहले से ही उल्लेख किया गया है, एक मॉड्यूल प्रकार है।

दूसरा एक वर्ग प्रकार है।

class type fooSansBar = object 
    method a: string 
    method b: int 
end 

और एक वर्ग के प्रकार fooConBar:

class type fooConBar = object 
    inherit fooSansBar 
    method bar: char 
end 

यह आपको एक fooConBar कहीं भी एक fooSansBar की आवश्यकता है का उपयोग करने की अनुमति देगा आप एक वर्ग प्रकार (इंटरफेस) fooSansBar लिख सकते हैं। अब आप एक fooSansBar बना सकते हैं, प्रकार निष्कर्ष का उपयोग कर:

let fsb = object 
    method a = "a" 
    method b = 3 
end 

अब, fsb के प्रकार के रूप में जॉन ने संकेत दिया, <a: string; b: int> होता है, लेकिन यह OCaml के संरचनात्मक subtyping की वजह से एक fooSansBar के रूप में पूरी तरह से प्रयोग करने योग्य है।

संबंधित मुद्दे