ठीक है। यहां समस्या बहुत सार है। धैर्य रखने के लिए अनुरोध।संकलक को आश्वस्त करते हुए कि वैध उदाहरण श्रृंखला
मेरे पास "इकाइयों" का एक गुच्छा है, जिसमें प्रत्येक के पास कुछ निश्चित गुण हैं। इन गुणों इस तरह, Seq
कक्षा में परिभाषित कर रहे हैं:
class Seq a x y where
break :: x -> (a, y)
build :: a -> y -> x
वैचारिक रूप से, a
प्रकार महत्वपूर्ण प्रकार, x
एक a
उत्पन्न करने के लिए इस्तेमाल किया संदर्भ है, और y
किसी भी आगे Seq
उत्पन्न करने के लिए इस्तेमाल किया संदर्भ है उदाहरणों। break
Seq
नीचे तोड़ता है, build
आपको इसे पुनर्निर्माण करने की अनुमति देता है।
व्यक्तिगत Seq
उदाहरणों पर, यह ठीक काम करता है।
data a :/: b = a :/: b deriving (Eq, Ord)
infixr :/:
इस पूरे ऑपरेशन के लक्ष्य Seq
उदाहरणों रचना करने में सक्षम होना है: हालांकि, मैं भी एक डेटा निर्माता है कि इस तरह दिखता है।
उदाहरण के लिए, अगर मैं a
, b
, और c
Seq
ऐसी है कि a
के सभी उदाहरणों है के संदर्भ फ़ीड b
में और b
के c
में फ़ीड, तो मैं अपने आप एक Seq
उदाहरण a :/: b :/: c
के लिए होना चाहिए। इसे सेट करने के लिए कक्षा रिकर्सिव डेटा प्रकार के माध्यम से काफी सरल है:
instance (Seq a x y, Seq b y z) => Seq (a :/: b) x z where
break x = let
(a, y) = break x :: (a, y)
(b, z) = break y :: (b, z)
in (a :/: b, z)
build (a :/: b) z = let
y = build b z :: y
x = build a y :: x
in x
समस्या यह है कि मैं इसका उपयोग नहीं कर सकता। अगर मैं निम्नलिखित तीन Seq
उदाहरणों को परिभाषित:
data Foo
instance Seq Foo Integer Bool
data Bar
instance Seq Bar Bool Bar
data Baz
instance Seq Baz Bar()
और एक अच्छी तरह से टाइप किया break
समारोह (कार्यान्वयन विवरण संशोधित, और अधिक के लिए here देखें):
myBreak :: Integer -> (Foo :/: Bar :/: Baz)
myBreak = fst . break' where
break' = break :: Integer -> (Foo :/: Bar :/: Baz,())
तो मैं नहीं कर सकता यहां तक कि संकलन:
No instances for (Seq Foo Integer y, Seq Bar y y1, Seq Baz y1())
arising from a use of `break'
Possible fix:
add instance declarations for
(Seq Foo Integer y, Seq Bar y y1, Seq Baz y1())
In the expression: break :: Integer -> (Foo :/: (Bar :/: Baz),())
In an equation for break':
break' = break :: Integer -> (Foo :/: (Bar :/: Baz),())
In an equation for `myBreak':
myBreak
= fst . break'
where
break' = break :: Integer -> (Foo :/: (Bar :/: Baz),())
यह मुझे लगता है कि myBreak
की तरह यह सुनिश्चित नहीं हो सकता है कि Foo → Bar → Baz से संदर्भों का "काम करने वाला धागा" है। मैं संकलक को कैसे समझा सकता हूं कि यह अच्छी तरह से टाइप किया गया है?
यह प्रोग्रामिंग प्रकार में मेरे पहले भ्रमण में से एक है, इसलिए निस्संदेह मैं कुछ अच्छी तरह से स्थापित नियमों को तोड़ रहा हूं। मैं यहां बहुत उत्सुक हूं कि मैं यहां क्या कर रहा हूं, लेकिन मैं अपने लक्ष्यों को बेहतर तरीके से प्राप्त करने के लिए सुझावों के लिए भी खुला हूं।
मैं इस बारे में और अधिक सोचने की कोशिश करूंगा, लेकिन केवल एक अनुमान है, आमतौर पर जब आपके पास "कोई उदाहरण नहीं है ..." त्रुटियों जहां पॉलिफोर्फिक (उदाहरण के लिए 'सीक फू इंटीजर वाई' की तरह है) और आप इसका मतलब यह नहीं था कि कार्यात्मक निर्भरता इसे बेहतर बना सकती है। – Owen