2011-12-24 12 views
9

मैं निम्नलिखित रिकॉर्ड परिभाषित मिल गया है:रिकॉर्ड के हास्केल "आश्रित" फ़ील्ड?

data Option = Option { 
    a :: Maybe String, 
    b :: Either String Int 
} deriving (Show) 

मेरे लिए वैसे भी वहाँ है लागू करने के लिए है कि जब एक Nothing है, ख एक Left होना चाहिए और जब एक Just है, ख एक Right होना चाहिए? शायद प्रेत के प्रकार, या कुछ और के साथ? या क्या मुझे पूरी चीज़ को किसी और के अंदर लपेटना चाहिए और इसे Either String (String, Int) बनाना चाहिए?

+0

मुझे नहीं लगता कि हास्केल 2010 में ऐसा कुछ भी है जो आपके पूर्व समाधान में इसकी अनुमति देता है। मैं सुझाव देता हूं कि 'या तो स्ट्रिंग (स्ट्रिंग, इंट)', या एक आइसोमोर्फिक प्रकार जैसे 'डेटा विकल्प = विकल्प ए स्ट्रिंग' के लिए जा रहा है। OptionB स्ट्रिंग Int', जहां रचनाकारों के समझदार नाम हैं। –

+1

इसका सबसे अच्छा जवाब देने के लिए, * ए * और 'बी' से जुड़े * अर्थ * को जानना महत्वपूर्ण है। ऐसा क्यों है कि कभी-कभी आपके पास 'ए' नहीं है (उदा। यह 'कुछ भी नहीं' है)? 'बी' को 'स्ट्रिंग' * या * इंट 'के रूप में प्रस्तुत करना ठीक क्यों है? आप उस प्रतिबंध को लागू क्यों करना चाहते हैं जिसके बारे में आप बात कर रहे थे? यह मुझे प्रारंभिक इंप्रेशन देता है कि 'बी' अच्छी तरह परिभाषित नहीं है। –

उत्तर

17

तुम सिर्फ दो संभावित आकार के लिए दो कंस्ट्रक्टर्स उपयोग करना चाहिए:

data Option = NoA String | WithA String Int 

बेशक, आप उन्हें बेहतर नाम, वे क्या प्रतिनिधित्व के आधार पर देना चाहिए। प्रेत प्रकार निश्चित रूप से यहां अधिक हैं, और मैं Either से बचने का सुझाव दूंगा - Left और Right बहुत ही स्वयं-दस्तावेज निर्माता नाम नहीं हैं।

यह समझ में आता है, तो एक ही डेटा प्रतिनिधित्व के रूप में दोनों ख क्षेत्र के किसी भी शाखाओं व्याख्या करने के लिए, तो आप एक समारोह है कि इस व्याख्या को दर्शाता है परिभाषित करना चाहिए:

b :: Option -> MeaningOfB 
b (NoA s) = ... 
b (WithA t n) = ... 

आप क्षेत्रों है कि एक ही नहीं रहना है, तो कोई फर्क नहीं पड़ता कि पसंद क्या है, आपको उन सभी के साथ एक नया डेटा प्रकार बनाना चाहिए, और इसे दोनों रचनाकारों में शामिल करना चाहिए। यदि आप प्रत्येक कन्स्ट्रक्टर को रिकॉर्ड बनाते हैं, तो आप सामान्य क्षेत्र को प्रत्येक कन्स्ट्रक्टर में एक ही नाम दे सकते हैं, ताकि आप इसे किसी भी Option मान से पैटर्न-मिलान के बिना निकाल सकें।

असल में, का अर्थ यह है कि स्ट्रिंग के लिए का मतलब नहीं है: यह अन्य फ़ील्ड के बारे में क्या बदलता है, और यह क्या रहता है? संबंधित रचनाकारों में जो भी बदलाव होना चाहिए; जो कुछ भी रहता है उसे अपने ही प्रकार में फैलाया जाना चाहिए। (यह सामान्य रूप से एक अच्छा डिजाइन सिद्धांत है!)

यदि आप ओओपी पृष्ठभूमि से आते हैं, तो आप विरासत की बजाय संरचना के तर्क के संदर्भ में इसके बारे में सोच सकते हैं - लेकिन समानता को बहुत दूर नहीं ले जाने का प्रयास करें।

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