मैं कुछ हास्केल कोड लिखने की कोशिश कर रहा हूं जिसमें कई डेटा प्रकार हैं, जिनमें से प्रत्येक में कई कार्यान्वयन हो सकते हैं। ऐसा करने के लिए, मैं प्रत्येक डेटा प्रकार को class
के रूप में परिभाषित करता हूं जिनकी विधियां प्रासंगिक रचनाकार और चयनकर्ता हैं, और फिर दिए गए रचनाकारों और चयनकर्ताओं के संदर्भ में उस वर्ग के सदस्यों पर सभी परिचालनों को लागू करते हैं।प्रकार के साथ मज़ा! एकाधिक उदाहरण घोषणाओं को हल करना
उदाहरण के लिए, शायद A
एक बहुपद वर्ग है जो एक SparsePoly
या एक DensePoly
और B
के रूप में एक प्रतिनिधित्व हो सकता है (तरीकों getCoefficients
और makePolynomial
साथ) एक जटिल संख्या वर्ग जो हो सकता है (तरीकों getReal
, getImag
और makeComplex
के साथ) ComplexCartesian
या ComplexPolar
के रूप में दर्शाया गया है।
मैं नीचे एक न्यूनतम उदाहरण reproduced गए हैं। मेरे पास दो वर्ग A
और B
हैं जिनमें से प्रत्येक में कार्यान्वयन है। मैं स्वचालित रूप से Num
के उदाहरणों में दोनों वर्गों के सभी उदाहरण बनाना चाहता हूं (इसके लिए FlexibleInstances
और UndecidableInstances
प्रकार एक्सटेंशन की आवश्यकता है)। यह ठीक काम करता है जब मैं केवल A
या B
में से एक है, लेकिन जब मैं दोनों के साथ संकलित करने के लिए प्रयास करते हैं, मैं निम्नलिखित त्रुटि मिलती है:
Duplicate instance declarations:
instance [overlap ok] (A a, Num x, Show (a x), Eq (a x)) =>
Num (a x)
-- Defined at test.hs:13:10-56
instance [overlap ok] (B b, Num x, Show (b x), Eq (b x)) =>
Num (b x)
-- Defined at test.hs:27:10-56
मुझे लगता है 'डुप्लिकेट उदाहरण घोषणाओं' संदेश है कि इसकी वजह एक डेटा प्रकार A
और B
दोनों का उदाहरण बनाया जा सकता है। मैं संकलक को एक वादा करने में सक्षम होना चाहता हूं कि मैं ऐसा नहीं करूँगा, या संभवतः किसी वर्ग का उपयोग करने के लिए डिफ़ॉल्ट वर्ग निर्दिष्ट करता हूं कि एक प्रकार दोनों वर्गों का एक उदाहरण है।
क्या ऐसा करने का कोई तरीका है (शायद एक और प्रकार का एक्सटेंशन?) या यह कुछ है जिसके साथ मैं फंस गया हूं?
यहाँ मेरी कोड है:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
class A a where
fa :: a x -> x
ga :: x -> a x
data AImpl x = AImpl x deriving (Eq,Show)
instance A AImpl where
fa (AImpl x) = x
ga x = AImpl x
instance (A a, Num x, Show (a x), Eq (a x)) => Num (a x) where
a1 + a2 = ga (fa a1 + fa a2)
-- other implementations go here
class B b where
fb :: b x -> x
gb :: x -> b x
data BImpl x = BImpl x deriving (Eq,Show)
instance B BImpl where
fb (BImpl x) = x
gb x = BImpl x
instance (B b, Num x, Show (b x), Eq (b x)) => Num (b x) where
-- implementations go here
संपादित करें: अपने आप को स्पष्ट करने के लिए, मैं किसी भी व्यावहारिक कोड इस तकनीक का इस्तेमाल लिखने की कोशिश कर नहीं कर रहा हूँ। मैं इसे टाइप सिस्टम और एक्सटेंशन को बेहतर ढंग से समझने में मदद करने के लिए एक अभ्यास के रूप में कर रहा हूं।
संबंधित: [मैं कैसे लिखूं, "अगर टाइपक्लास ए, तो यह भी परिभाषा द्वारा बी का एक उदाहरण है।"] (Http://stackoverflow.com/a/3216937/98117)। – hammar