2010-01-31 9 views
12

सबसे पहले, यह प्रश्न हास्केल के लिए 100% विशिष्ट नहीं है, टाइपक्लास, इंटरफेस और प्रकार के सामान्य डिज़ाइन पर टिप्पणी करने के लिए स्वतंत्र महसूस करें।हास्केल फ़ंक्शन हस्ताक्षर में डेटाटाइप के टाइपक्लास को घुमाने में क्यों रोकता है?

मैं LYAH - creating types and typeclasses निम्नलिखित पढ़ रहा हूँ कि मैं पारित होने के बारे में अधिक जानकारी के लिए देख रहा हूँ है:

Data (Ord k) => Map k v = ... 

हालांकि, यह हास्केल में एक बहुत मजबूत सम्मेलन है में बाधाओं typeclass जोड़ने कभी नहीं करने के लिए डेटा घोषणाएं क्यूं कर? ठीक है, क्योंकि हमें बहुत लाभ नहीं होता है, लेकिन हम बाधाओं को और अधिक कक्षा लिखते हैं, भले ही हमें की आवश्यकता न हो। अगर हम मानचित्र के वी के लिए डेटा घोषणा में ऑर्ड के बाधा डालते हैं या नहीं करते हैं, तो हमें को फ़ंक्शन में बाधा डालना होगा, जो नक्शा में कुंजियां हो सकती हैं। लेकिन अगर हम डेटा घोषणा में बाधा डाल नहीं करते, हम कार्यों कि परवाह नहीं है की प्रकार घोषणाओं में (Ord ट) => डाल करने के लिए कुंजी आदेश दिया जा सकता है कि क्या नहीं है या नहीं। इस तरह के फ़ंक्शन का एक उदाहरण है, जो कि मैपिंग लेता है और इसे सहयोगी सूची में परिवर्तित करता है। इसका प्रकार हस्ताक्षर toList :: मैप के ए -> [(के, ए)] है। यदि मानचित्र केवी के पास डेटा घोषणा में एक प्रकार की बाधा थी, तो लिस्ट के लिए प्रकार को सूची :: (Ord k) => मानचित्र का -> [(के, ए)] होना चाहिए, भले ही फ़ंक्शन आदेश के अनुसार कुंजी की तुलना नहीं करता है।

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

पहली बार मैंने इसे पढ़ा, यह एक "हैक (या कामकाज) प्रतिक्रिया" को स्वीकार किया। कुछ विचारों के साथ दूसरे पढ़ने पर, यह चालाक लग रहा था। तीसरे पढ़ने पर, ओओ दुनिया के लिए एक समझौता ड्राइंग, यह फिर से एक हैक की तरह लग रहा था।

तो मैं यहां हूं।

उत्तर

4

डेटा घोषणाओं में टाइपक्लास बाधाओं से बचने का मुख्य कारण यह है कि वे बिल्कुल कुछ भी नहीं पूरा करते हैं; वास्तव में, मेरा मानना ​​है कि जीएचसी इस तरह के एक वर्ग संदर्भ को "बेवकूफ संदर्भ" के रूप में संदर्भित करता है। इसका कारण यह है कि क्लास डिक्शनरी डेटा प्रकार के मानों के साथ नहीं ले जाती है, इसलिए आपको वैसे भी मूल्यों पर चल रहे प्रत्येक फ़ंक्शन में इसे जोड़ना होगा।

डेटा प्रकार पर चल रहे कार्यों पर टाइपक्लास बाधा "मजबूर" करने के तरीके के रूप में, यह वास्तव में कुछ भी पूरा नहीं करता है; कार्यों को आम तौर पर जितना संभव हो सके पॉलीमोर्फिक होना चाहिए, तो उन चीज़ों पर बाधा क्यों मजबूर करें जिनकी आवश्यकता नहीं है?

इस बिंदु पर, आपको लगता है कि मूल्यों के साथ शब्दकोश को ले जाने के लिए एडीटी के अर्थशास्त्र को बदलना संभव होना चाहिए। वास्तव में, ऐसा लगता है कि यह GADT एस का पूरा बिंदु है; उदाहरण के लिए, आप कर सकते हैं:

data Foo a where { Foo :: (Eq a) => a -> Foo a } 
eqfoo :: Foo t -> Foo t -> Bool 
eqfoo (Foo a) (Foo b) = a == b 

सूचना है कि eqfoo के प्रकार के रूप में यह फू डेटा प्रकार अपने आप में "किया" है, समीकरण बाधा जरूरत नहीं है।

+0

मैं हास्केल के लिए काफी नया हूं, एक संक्षिप्त विवरण क्या है कि एक जीएडीटी सहायक (या लिंक) होता। –

+0

मैंने उस सेक्शन को थोड़ा सा काम किया है, और जीएडीटी के लिए जीएचसी दस्तावेज के लिए एक लिंक जोड़ा है। यदि कोई और जीएडीटी के बेहतर स्पष्टीकरण पर एक दरार लेना चाहता है, तो इसका स्वागत होगा! – mithrandi

9

शायद Map k v बिंदु को चित्रित करने का सबसे अच्छा उदाहरण नहीं था। Map की परिभाषा को देखते हुए, भले ही कुछ ऐसे फ़ंक्शन हैं जिन्हें (Ord k) बाधा की आवश्यकता नहीं होगी, इसके बिना Map बनाने का कोई भी संभावित तरीका नहीं है।

अक्सर यह पता चलता है कि एक प्रकार के कार्यों के उप-सेट के साथ एक प्रयोग काफी उपयोगी है जो किसी विशेष बाधा के बिना काम करता है, भले ही आपने बाधा को अपने मूल डिजाइन के स्पष्ट पहलू के रूप में देखा हो। ऐसे मामलों में, प्रकार की घोषणा से बाधा छोड़ने से यह अधिक लचीला हो जाता है।

उदाहरण के लिए, Data.List में बहुत सारे फ़ंक्शन हैं जिनमें (Eq a) की आवश्यकता होती है, लेकिन निश्चित रूप से सूचियां बिना किसी बाधा के उपयोगी होती हैं।

+1

"इसके बिना मानचित्र बनाने का कोई भी संभावित तरीका नहीं है।" - यही कारण है कि मैंने हमेशा महसूस किया है कि ओर्ड जैसे चीजें उन कार्यों पर संदर्भित करती हैं जो _consume_ नक्शे अनावश्यक होंगी, और जीएडीटी मैचों के संदर्भों को प्रस्तुत करने का कारण भी होगा। तथ्य यह है कि मेरे पास 'मैप के वी' है, पहले से ही पर्याप्त प्रमाण है कि के आदेश दिया गया है। यदि मैं कर रहा हूं तो मानचित्र से चीजें निकालने जा रही हैं, उदाहरण के लिए, मुझे ऑर्ड इंस्टेंस की आवश्यकता क्यों होनी चाहिए? – mokus

7

संक्षिप्त उत्तर यह है: हास्केल ऐसा करता है क्योंकि भाषा की कल्पना लिखी जाती है।

विस्तृत उत्तर GHC documentation language extensions section से उद्धृत करना शामिल है:

कि मानक हास्केल-98 वाक्य रचना में घोषित किया जा सकता भी GADT शैली सिंटैक्स का उपयोग घोषित किया जा सकता किसी भी डेटा प्रकार। पसंद काफी हद तक स्टाइलिस्ट है, लेकिन जीएडीटी-स्टाइल घोषणाएं एक महत्वपूर्ण सम्मान में भिन्न होती हैं: वे डेटा कन्स्ट्रक्टरों पर वर्ग की बाधाओं का अलग-अलग व्यवहार करते हैं। विशेष रूप से, यदि निर्माता को टाइप-क्लास संदर्भ दिया जाता है, तो वह संदर्भ पैटर्न मिलान द्वारा उपलब्ध कराया जाता है। उदाहरण के लिए:

data Set a where 
    MkSet :: Eq a => [a] -> Set a 

(...)

सभी इस व्यवहार एक डेटा प्रकार घोषणा (Section 4.2.1 of the Haskell 98 Report) पर संदर्भों की हास्केल 98 के अजीब उपचार के विपरीत है। हास्केल 98 परिभाषा में

data Eq a => Set' a = MkSet' [a] 

MkSet 'ऊपर MkSet के रूप में एक ही प्रकार देता है। लेकिन एक (ईक ए) बाधा उपलब्ध कराने के बजाय, एमकेसेट पर पैटर्न-मिलान के लिए एक (ईक्यू) बाधा की आवश्यकता होती है! जीएचसी इस व्यवहार को ईमानदारी से लागू करता है, हालांकि यह अजीब है। लेकिन जीएडीटी-स्टाइल घोषणाओं के लिए, जीएचसी का व्यवहार अधिक उपयोगी है, साथ ही साथ अधिक सहज ज्ञान युक्त है।

1

मैं कहना है कि यदि आप चिंतित हैं कि एक एक वस्तु है कि इसके संचालन के लिए की कमी की आवश्यकता है लेकिन इसके निर्माण के लिए नहीं है का निर्माण कर सकते हैं, mkFoo कहते हैं, आप हमेशा कृत्रिम बाधा mkFoo पर डाल सकते हैं चाहते हैं कोड का उपयोग करने वाले लोगों द्वारा टाइपक्लास के उपयोग को लागू करने के लिए कार्य करें। यह विचार गैर एमकेएफयू प्रकार के कार्यों तक भी फैला है जो फू पर काम करते हैं। फिर मॉड्यूल को परिभाषित करते समय, ऐसी किसी भी चीज को निर्यात न करें जो बाधाओं को लागू नहीं करता है।

हालांकि मुझे यह मानना ​​है कि मुझे इसके लिए कोई उपयोग नहीं दिख रहा है।