मान लीजिए कि मेरे पास दो डेटा प्रकार हैं Foo और Bar। फू में फ़ील्ड एक्स और वाई है। बार में फ़ील्ड एक्स और जेड है। मैं एक ऐसा फ़ंक्शन लिखने में सक्षम होना चाहता हूं जो पैरामीटर या बार को पैरामीटर के रूप में लेता है, एक्स मान निकालता है, उस पर कुछ गणना करता है, और उसके बाद x मान सेट के साथ एक नया Foo या Bar देता है।हास्केल रिकॉर्ड वाक्यविन्यास और प्रकार वर्ग
class HasX a where
getX :: a -> Int
setX :: a -> Int -> a
data Foo = Foo Int Int deriving Show
instance HasX Foo where
getX (Foo x _) = x
setX (Foo _ y) val = Foo val y
getY (Foo _ z) = z
setY (Foo x _) val = Foo x val
data Bar = Bar Int Int deriving Show
instance HasX Bar where
getX (Bar x _) = x
setX (Bar _ z) val = Bar val z
getZ (Bar _ z) = z
setZ (Bar x _) val = Bar x val
modifyX :: (HasX a) => a -> a
modifyX hasX = setX hasX $ getX hasX + 5
समस्या यह है कि उन सभी getters और setters लिखने के लिए दुखदाई है, खासकर अगर मैं खेतों के बहुत सारे है कि वास्तविक दुनिया डेटा प्रकार के साथ फू और बार की जगह,:
यहाँ एक दृष्टिकोण है।
हास्केल का रिकॉर्ड वाक्यविन्यास इन अभिलेखों को परिभाषित करने का एक बहुत अच्छा तरीका प्रदान करता है। लेकिन, अगर मैं इस
data Foo = Foo {x :: Int, y :: Int} deriving Show
data Bar = Foo {x :: Int, z :: Int} deriving Show
जैसे रिकॉर्ड को परिभाषित करने का प्रयास करता हूं तो मुझे एक त्रुटि मिल जाएगी कि x को कई बार परिभाषित किया गया है। और, मैं एक प्रकार के वर्ग के इन हिस्सों को बनाने के लिए कोई रास्ता नहीं देख रहा हूं ताकि मैं उन्हें संशोधित करने के लिए पास कर सकूं।
क्या इस समस्या को हल करने का कोई अच्छा साफ तरीका है, या क्या मैं अपने स्वयं के गेटर्स और सेटर्स को परिभाषित करने के साथ अटक गया हूं? एक और तरीका रखो, क्या टाइप क्लास (दोनों गेटर्स और सेटर्स) के साथ रिकॉर्ड सिंटैक्स द्वारा बनाए गए कार्यों को जोड़ने का कोई तरीका है?
संपादित
यहाँ वास्तविक समस्या मैं हल करने के लिए कोशिश कर रहा हूँ है। मैं संबंधित प्रोग्रामों की एक श्रृंखला लिख रहा हूं जो सभी अपने कमांड लाइन विकल्पों को पार्स करने के लिए System.Console.GetOpt का उपयोग करते हैं। इन कार्यक्रमों में बहुत सारे कमांड लाइन विकल्प होंगे, लेकिन कुछ कार्यक्रमों में अतिरिक्त विकल्प हो सकते हैं। मैं चाहता हूं कि प्रत्येक प्रोग्राम अपने सभी विकल्प मान वाले रिकॉर्ड को परिभाषित करने में सक्षम हो। इसके बाद मैं एक डिफ़ॉल्ट रिकॉर्ड मान से शुरू होता हूं जिसे कमांड लाइन तर्कों को प्रतिबिंबित करने वाला अंतिम रिकॉर्ड प्राप्त करने के लिए एक स्टेटटी मोनड और गेटऑप्ट के माध्यम से परिवर्तित किया जाता है। एक कार्यक्रम के लिए, यह दृष्टिकोण वास्तव में अच्छी तरह से काम करता है, लेकिन मैं सभी कार्यक्रमों में कोड का पुन: उपयोग करने का एक तरीका खोजने का प्रयास कर रहा हूं।
यदि आपके पास एक ही डेटा प्रकार 'डेटा FooBar = Foo {x :: Int, y :: Int} था। बार {x :: Int, z :: Int} 'आपको यह समस्या नहीं होगी। यदि आपके डेटा प्रकार अलग-अलग मॉड्यूल में थे तो आप '{- # LANGUAGE DisambiguateRecordFields # -} 'का उपयोग कर सकते हैं। आपके वर्तमान डिजाइन के साथ चिपकने के लिए कोई कारण? – ephemient