2010-05-18 12 views
6

एफ # में, मैं क्या मैं एक काफी मानक सार डाटाटाइप के रूप में देखते करना चाहते हैं:एफ #: एक हस्ताक्षर में एक प्रकार संक्षेप छुपा नहीं सकता है? क्यों नहीं?

// in ADT.fsi 
module ADT 
    type my_Type 

// in ADT.fs 
module ADT 
    type my_Type = int 

दूसरे शब्दों में, मॉड्यूल के अंदर कोड जानता है कि my_Type एक पूर्णांक है, लेकिन कोड के बाहर नहीं है। हालांकि, एफ # में एक प्रतिबंध है, जहां संक्षेप में विशेष रूप से हस्ताक्षर द्वारा छुपाया नहीं जा सकता है। यह कोड एक कंपाइलर त्रुटि देता है, और प्रतिबंध here वर्णित है।

यदि My_Type इसके बजाय एक भेदभावपूर्ण संघ था, तो कोई कंपाइलर त्रुटि नहीं है। मेरा सवाल है, प्रतिबंध क्यों? मुझे लगता है कि एसएमएल और ओकम्ल में ऐसा करने में सक्षम होने के नाते, और इसके अलावा, क्या यह एक अमूर्त डेटाटाइप बनाने के दौरान एक सुंदर मानक बात नहीं है?

धन्यवाद

उत्तर

10

गणेश बताते हैं, यह एफ # कंपाइलर (और .NET रनटाइम) की तकनीकी सीमा है, क्योंकि प्रकार संक्षेप को संकलन के दौरान वास्तविक प्रकार द्वारा प्रतिस्थापित किया जाता है। नतीजतन, यदि आप एक समारोह लिखें:

int foo(int a); 

तो संक्षिप्त नाम के वास्तविक प्रकार से छिपा हुआ था:

let foo (a:MyType) : MyType = a + 1 

संकलक यह निम्न हस्ताक्षर के साथ एक .NET पद्धति के रूप में संकलित कर देगा लाइब्रेरी के उपयोगकर्ता, तो वे यह पहचानने में सक्षम नहीं होंगे कि foo फ़ंक्शन वास्तव में MyType के साथ काम कर रहा है (यह जानकारी शायद कुछ F #-विशिष्ट मेटा-डेटा में संग्रहीत है, लेकिन यह अन्य .NET भाषाओं के लिए उपलब्ध नहीं है .. ।)।

type MyType = MT of int 
let foo (MT a) = MT(a + 1) 

कार्य प्रकार के इस प्रकार के साथ काफी सुविधाजनक है:

शायद यह limiation के लिए सबसे अच्छा समाधान के रूप में एक एकल मामले संघ भेदभाव के प्रकार को परिभाषित करने के लिए है। यह कुछ ओवरहेड जोड़ता है (प्रकार के मूल्य का निर्माण करते समय नई वस्तुएं बनाई गई हैं), लेकिन अधिकांश स्थितियों में यह एक बड़ा मुद्दा नहीं होना चाहिए।

+0

हाँ, धन्यवाद टॉमस और गणेश भी। अब मैं इस मुद्दे को समझता हूं, और मैं देख सकता हूं कि, इस संकलन रणनीति को देखते हुए, यह समस्या एक परिणाम है। यह थोड़ा निराशाजनक है क्योंकि मैं लगभग पूरी तरह से एफ # अंतरिक्ष में काम कर रहा हूं लेकिन मुझे पता है कि अंतःक्रियाशीलता बहुत महत्वपूर्ण है, इसलिए मैं शिकायत नहीं करूंगा! :-) –

1

मैं क्या समझ एफ # से एक संक्षिप्त नाम एक हस्ताक्षर से छुपा होने की अनुमति नहीं देता है।

मुझे यह link मिला जहां ब्लॉगर ने इस पर टिप्पणी की लेकिन मुझे यकीन नहीं है कि यह मामला क्यों है।

मेरी धारणा यह है कि यह सीएलआर पर अन्य भाषाओं के साथ अधिक प्रभावी इंटरऑप की अनुमति देने के लिए एक संयम सेट है।

4

ध्यान दें कि आप एक मॉड्यूल के भीतर निजी के रूप में एक प्रकार संक्षिप्त नाम को परिभाषित कर सकते हैं:

// File1.fs 
module File1 
    type private MyType = int 
    let e : MyType = 42 
    let f (x:MyType) = x+1 

// Program.fs 
module Program 
do printfn "%A" (File1.f File1.e) 

मैं स्पष्ट नहीं क्यों आप इसे एक हस्ताक्षर के साथ नहीं छुपा सकते हूं; मैंने इसे देखने के लिए एक बग लॉग किया।

+0

सच है, लेकिन जिस अर्थ में मैं एडीटी की कल्पना कर रहा हूं, क्लाइंट को इस प्रकार के बारे में जानने की अनुमति देता है, सिर्फ इसका प्रतिनिधित्व नहीं। यदि मेरे पास फ़ाइल 1 में एक और फ़ंक्शन है, खाली(): MyType = 1 क्या मैं इस फ़ंक्शन को फ़ाइल 1 के बाहर से कॉल कर सकता हूं और इसके परिणाम को f में पास कर सकता हूं? –

+0

हां (मैंने ऊपर उदाहरण संपादित किया है)। लेकिन मैं तुम्हारा बिंदु देखता हूं, यह कट्टरपंथी है, उदाहरण के लिए File1.MyType इंटेलिजेंस सूची में एक इकाई के रूप में प्रकट नहीं होता है, हालांकि फ़ाइल 1। MyType f और e के हस्ताक्षर में दिखाई देता है। – Brian

+0

ध्यान दें कि यह आपको मॉड्यूल के बाहर से 'File1.f 42' जैसी कुछ करने से नहीं रोकता है, इसलिए' MyType = int' 'जानकारी वास्तव में छिपी नहीं है। तो दुख की बात यह वांछित प्रभाव प्राप्त नहीं करता है। – sepp2k

5

एफ # में संक्षेपों को संकलित किया गया है (यानी संकलित कोड int का उपयोग करेगा, MyType नहीं), इसलिए आप उन्हें उचित रूप से सार नहीं बना सकते हैं। सिद्धांत रूप में संकलक एफ # दुनिया के भीतर अमूर्तता को लागू कर सकता है, लेकिन यह बहुत उपयोगी नहीं होगा क्योंकि यह अभी भी अन्य भाषाओं में रिसाव होगा।

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