2010-07-13 8 views
26

मैं ocaml मॉड्यूल और उनके संकलन के बारे में एक विशिष्ट बात को समझने के लिए कोशिश कर रहा हूँ:अतिरिक्तता (मिलीग्राम/MLI)

हूँ मैं पहले से ही एक .mli विशिष्ट .ml कार्यान्वयन के अंदर में घोषित प्रकार redeclare करने के लिए मजबूर?

बस एक उदाहरण देने के लिए:

(* foo.mli *) 
type foobar = Bool of bool | Float of float | Int of int 

(* foo.ml *) 
type baz = foobar option 

यह, के बारे में इंटरफेस/कार्यान्वयन सोच के अपने सामान्य तरीके के अनुसार, ठीक होना चाहिए, लेकिन यह कहते

Error: Unbound type constructor foobar

साथ संकलित करने के लिए प्रयास करते हुए
ocamlc -c foo.mli 
ocamlc -c foo.ml 

बेशक अगर मैं foobar घोषित करता हूं तो त्रुटि गायब हो जाती है foo.ml अंदर भी है लेकिन यह एक जटिल तरीके से मैं हर बदलाव पर synched चीजें रखने के लिए लगता है।

वहाँ एक रास्ता यह अतिरेक या मैं प्रकार हर बार redeclare करने के लिए मजबूर कर रहा हूँ से बचने के लिए है?

अग्रिम

उत्तर

15

OCaml कार्यान्वयन (.ml से इंटरफेस (.mli) अलग करने के लिए आप के लिए मजबूर करने की कोशिश करता है अधिकांश समय, यह एक अच्छी बात है;। मूल्यों के लिए, आप इंटरफ़ेस में प्रकार प्रकाशित करें, और में कोड रखने कार्यान्वयन आप कह सकते हैं कि OCaml अमूर्त की एक निश्चित राशि लागू कर रहा है। (इंटरफेस प्रकाशित किया जाना चाहिए; इंटरफेस में कोई कोड)।

प्रकारों के लिए, अक्सर, कार्यान्वयन इंटरफेस के समान होता है: दोनों राज्यों का प्रकार एक विशेष प्रतिनिधित्व है (और शायद यह कि प्रकार की घोषणा जेनरेटिव है)। यहां, कोई अमूर्तता नहीं हो सकती है, क्योंकि कार्यान्वयनकर्ता के पास उस प्रकार के बारे में कोई जानकारी नहीं है जिसे वह प्रकाशित नहीं करना चाहता। (अपवाद मूल रूप से होता है जब आप एक अमूर्त प्रकार घोषित करते हैं।)

यह देखने का एक तरीका यह है कि इंटरफ़ेस में पहले से ही कार्यान्वयन लिखने के लिए पर्याप्त जानकारी है। इंटरफ़ेस type foobar = Bool of bool | Float of float | Int of int को देखते हुए, केवल एक ही संभावित कार्यान्वयन है। तो एक कार्यान्वयन मत लिखो!

एक सामान्य मुहावरे एक मॉड्यूल होना है जो घोषणाओं को टाइप करने के लिए समर्पित है, और इसे केवल .mli बनाते हैं। चूंकि प्रकार मूल्यों पर निर्भर नहीं होते हैं, इसलिए यह मॉड्यूल आम तौर पर निर्भरता श्रृंखला में बहुत जल्दी आता है। अधिकांश संकलन उपकरण इस के साथ अच्छी तरह से सामना करते हैं; उदाहरण के लिए ocamldep सही काम करेगा। (यह केवल .ml होने पर एक फायदा है।)

इस दृष्टिकोण की सीमा तब होती है जब आपको यहां और वहां कुछ मॉड्यूल परिभाषाओं की भी आवश्यकता होती है। (एक सामान्य उदाहरण foo टाइप कर रहा है, फिर OrderedFoo : Map.OrderedType मॉड्यूल type t = foo के साथ मॉड्यूल, फिर 'a Map.Make(OrderedFoo).t से आगे की एक और प्रकार की घोषणा।) इन्हें इंटरफ़ेस फ़ाइलों में नहीं रखा जा सकता है। कभी-कभी कई परिभाषाओं में अपनी परिभाषाओं को तोड़ने के लिए स्वीकार्य है, पहले प्रकार का एक गुच्छा (types1.mli), फिर एक मॉड्यूल (mod1.mli और mod1.ml), फिर अधिक प्रकार (types2.mli)। अन्य बार (उदाहरण के लिए यदि परिभाषा रिकर्सिव हैं) तो आपको .ml के साथ .mli या डुप्लिकेशन के बिना रहना होगा।

14

हाँ, धन्यवाद आप प्रकार redeclare करने के लिए मजबूर कर रहे हैं। इसके बारे में एकमात्र तरीके हैं जिन्हें मैं जानता हूं

  • एक .mli फ़ाइल का उपयोग न करें; बस इंटरफ़ेस के साथ सब कुछ बेनकाब करें। भयानक विचार।

  • एक सच्चे स्रोत में इंटरफ़ेस घोषणाओं डुप्लिकेट करने से बचने के लिए एक साक्षर-प्रोग्रामिंग उपकरण या अन्य पूर्वप्रक्रमक का प्रयोग करें। बड़ी परियोजनाओं के लिए, हम इसे अपने समूह में करते हैं।

छोटी परियोजनाओं के लिए, हम सिर्फ प्रकार की घोषणाओं को डुप्लिकेट करते हैं। और इसके बारे में चिल्लाओ।

+0

मैं वहाँ एक '.ml' फ़ाइल मिलकर' .mli' में वर्णित प्रकार अनुमान लगाने के लिए अनुमति देता है में कोई सीमाएं होना चाहिए नहीं लगता। जो मैं वास्तविक कार्यान्वयन को समझता हूं __forces redundancy__ लेकिन यह भी कि __ दोनों हस्ताक्षर बराबर__ होना चाहिए, इसलिए यह प्रभावी रूप से समान घोषणाओं को दोगुना कर रहा है। यही कारण है कि मैंने सोचा कि उन्हें इन घोषणाओं के बारे में अवगत होना चाहिए, उन्हें कॉपी और पेस्ट किए बिना। प्रकार अनुमान एल्गोरिदम मेरे अनुसार समस्याओं का सामना नहीं करेगा। – Jack

+3

यह काफी अनावश्यकता को मजबूर नहीं करता है और न ही यह हस्ताक्षरों की समानता की आवश्यकता होती है, केवल एमएल फ़ाइल में घोषणा एमएलआई घोषणा से बराबर या अधिक विशिष्ट होनी चाहिए। एमएलआई का बिंदु इंटरफेस में जो दिख रहा है उसे परिभाषित करना है, क्योंकि आप इस प्रकार का पर्दाफाश नहीं करना चुन सकते हैं (जिस स्थिति में यह एमएलआई फाइल में नहीं है) या आप यह खुलासा कर सकते हैं कि एक प्रकार है, लेकिन नहीं इसका उपयोग किया जाता है (जिस स्थिति में प्रकार की घोषणा अलग होती है)। निश्चित रूप से आपकी स्थिति में संकलक के लिए यह समझ में आ जाएगा कि यह केवल प्रकार को मानने के बाद से है क्योंकि यह पूरी तरह से mli में परिभाषित है। –

+3

@Niki * मूल्य * घोषणाओं में कोई मजबूर अनावश्यकता नहीं है (जो कि किसी भी तरह से .ml में वैकल्पिक हैं), और व्यवहार में वह जगह है जहां "कम से कम विशिष्ट के रूप में" आता है। लेकिन 99% मामलों में एक * प्रकट प्रकार * घोषित एक इंटरफ़ेस में कार्यान्वयन में प्रकार की परिभाषा के समान है। यह अनावश्यक है, और परेशान है, लेकिन एक भाषा डिजाइनर के रूप में मैंने इस समस्या के बारे में कड़ी मेहनत की है और मैंने एक प्रस्ताव के साथ नहीं आया है जो मुझे लगता है कि दोनों सिद्धांत और ओकैमल से काफी बेहतर हैं। –

12

आप दे सकते हैं ocamlc मिलीलीटर फ़ाइल से आप के लिए MLI फाइल उत्पन्न:

ocamlc -i some.ml > some.mli 
3

सामान्य तौर पर, हाँ, आप प्रकार नकल करने की आवश्यकता है।

आप कैमलप 4 और pa_macro सिंटैक्स एक्सटेंशन (findlib पैकेज: camlp4.macro) के साथ इस पर काम कर सकते हैं। यह अन्य चीजों के साथ परिभाषित करता है, और निर्माण शामिल है। आप इसे सामान्य प्रकार की परिभाषाओं को एक अलग फ़ाइल में फैक्टर करने के लिए उपयोग कर सकते हैं और उस फ़ाइल को .ml और .mli फ़ाइलों दोनों में शामिल कर सकते हैं। मैंने इसे तैनात ओकैमल प्रोजेक्ट में नहीं देखा है, इसलिए, मुझे नहीं पता कि यह अनुशंसित अभ्यास के रूप में योग्य होगा, लेकिन यह संभव है।

हालांकि, साक्षर प्रोग्रामिंग समाधान क्लीनर आईएमओ है।

-3

नहीं है, MLI फ़ाइल में, बस कहते हैं कि "प्रकार foobar"। यह काम करेगा।