2011-08-26 18 views
7

के साथ सही abstractions प्राप्त करने में मुझे Haskell के प्रकार प्रणाली का उपयोग कर परेशानी हो रही है। मुझे यकीन है कि मेरी समस्या एक आम है, लेकिन मुझे नहीं पता कि मेरे प्रोग्राम के लिए विशिष्ट शर्तों को छोड़कर इसका वर्णन कैसे किया जाए।हास्केल के प्रकार सिस्टम

अवधारणाओं मैं प्रतिनिधित्व करने के लिए कोशिश कर रहा हूँ कर रहे हैं:

  • datapoints, कई रूपों में से एक लेता है, जिनमें से प्रत्येक, उदा (आईडी, मामलों की संख्या, नियंत्रण की संख्या), (आईडी, मामलों की संख्या, आबादी)

  • डाटापॉइंट्स और कुल जानकारी के सेट: (आईडी के कुल मामलों, कुल नियंत्रण, कुल नियंत्रण), जोड़ने/अंक को हटाने

मैं बिंदु प्रकार के एक वर्ग है और अपने स्वयं के प्रकार के रूप में बिंदु के प्रत्येक किस्म निर्धारित कर सकते हैं (ताकि बिंदु के प्रत्येक किस्म के लिए, वहाँ सेट के एक इसी किस्म है)। वैकल्पिक रूप से, मेरे पास प्रत्येक बिंदु के लिए एक बिंदु प्रकार और एक अलग डेटा कन्स्ट्रक्टर हो सकता है। इसी तरह अंक के सेट के लिए।

  • प्रकार वर्गों के साथ: से बचना समारोह नाम टक्कर कष्टप्रद हो जाएगा

    मैं प्रत्येक दृष्टिकोण के साथ कम से कम एक चिंता का विषय है। उदाहरण के लिए, दोनों प्रकार के अंक "मामलों की संख्या" निकालने के लिए फ़ंक्शन का उपयोग कर सकते हैं, लेकिन टाइप क्लास को इस फ़ंक्शन की आवश्यकता नहीं हो सकती क्योंकि कुछ अन्य बिंदु प्रकार में मामले नहीं हो सकते हैं।

  • प्रकार कक्षाओं के बिना: मैं डेटा कन्स्ट्रक्टर को, प्वाइंट मॉड्यूल (अन्य मूल्य, एक नया मूल्य बनाने के लिए सुरक्षित कार्य प्रदान करने) से निर्यात नहीं करना चाहता हूं। डेटा कन्स्ट्रक्टर के बिना, मैं यह निर्धारित करने में सक्षम नहीं होगा कि दिए गए प्वाइंट मान किस प्रकार के हैं।

कौन सा डिज़ाइन इन (और अन्य) समस्याओं को कम करने में मदद कर सकता है?

+0

किन परिस्थितियों आप अपने डेटा अंक इसी तरह का इलाज करने की आवश्यकता है में? आप कहते हैं कि प्रत्येक फॉर्म को अपनी खुद की सेट की आवश्यकता होगी, और "मामलों की संख्या" जैसे ऑपरेशंस सार्वभौमिक नहीं हैं। –

उत्तर

4

एससीएलवी के उत्तर पर थोड़ा विस्तार करने के लिए, निकटता से संबंधित अवधारणाओं का एक विस्तारित परिवार है जो मूल्य को डीकनस्ट्रक्चर करने के कुछ साधन प्रदान करने के लिए है: कैटमोर्फिज्म, जो सामान्यीकृत फ़ोल्ड होते हैं; चर्च-एन्कोडिंग, जो इसके संचालन के आधार पर डेटा का प्रतिनिधित्व करता है, और अक्सर आंशिक रूप से आंशिक रूप से उस मूल्य को लागू करने के बराबर होता है जो इसे deconstructs के मूल्य पर लागू करता है; सीपीएस बदलता है, जहां एक चर्च एन्कोडिंग एक संशोधित पैटर्न मैच जैसा दिखता है जो प्रत्येक मामले के लिए अलग निरंतरता लेता है; डेटा का प्रतिनिधित्व करने वाले संचालन के संग्रह के रूप में प्रतिनिधित्व करते हैं, आमतौर पर ऑब्जेक्ट उन्मुख प्रोग्रामिंग के रूप में जाना जाता है; और इसी तरह।

आपके मामले में, क्या आप चाहते हैं लगता है एक एक सार प्रकार, यानी एक ही है कि अपने आंतरिक प्रतिनिधित्व निर्यात नहीं करता है, लेकिन नहीं एक पूरी तरह से सील एक, यानी कि मॉड्यूल में कार्यों के लिए प्रतिनिधित्व खुला छोड़ देता है जो इसे परिभाषित करता है। Data.Map.Map जैसी चीजों के बाद यह वही पैटर्न है।आप शायद नहीं प्रकार वर्ग करना चाहते हैं, जैसे आप बल्कि डेटा बिंदु के एक ही प्रकार की एक मनमाना चुनाव पर की तुलना में, डेटा बिंदुओं की एक किस्म के साथ काम करने की जरूरत के बाद से यह लग रहा है चाहता हूँ।

सबसे अधिक संभावना, "स्मार्ट कंस्ट्रक्टर्स" मान बनाने के लिए, के कुछ संयोजन और विखंडन कार्यों की एक किस्म (जैसा ऊपर वर्णित) मॉड्यूल से निर्यात के लिए सबसे अच्छा प्रारंभिक बिंदु है। वहां से जाकर, मुझे उम्मीद है कि शेष बचे हुए विवरणों में अगला लेने के लिए एक स्पष्ट दृष्टिकोण होना चाहिए।

3
बाद समाधान (कोई प्रकार वर्ग), आप बल्कि कंस्ट्रक्टर्स से प्रकार पर एक catamorphism निर्यात कर सकते हैं के साथ

..

data MyData = PointData Double Double | ControlData Double Double Double | SomeOtherData String Double 

foldMyData pf cf sf d = case d of 
     (PointData x y) -> pf x y 
     (ControlData x y z) -> cf x y z 
     (SomeOtherData s x) -> sf s x 

इस तरह आप अपने डेटा जो चाहो में अलग खींचने के लिए एक रास्ता है (केवल मूल्यों को अनदेखा करने और उन कार्यों को पार करने सहित जो आपके द्वारा उपयोग किए जाने वाले किस प्रकार के कन्स्ट्रक्टर का उपयोग करते हैं) आपके डेटा को बनाने के लिए एक सामान्य तरीका प्रदान किए बिना।

2

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

नाम टक्कर समस्या आप का उल्लेख इस तरह प्रत्येक विशिष्ट क्षेत्र के लिए एक अलग प्रकार वर्ग बनाने के द्वारा हल किया जा सकता,:

class WithCases p where 
    cases :: p -> NumberOfCases 
संबंधित मुद्दे