2009-04-27 11 views
59

मैं हास्केल के लिए नया हूं और "असीमित प्रकार का निर्माण नहीं कर सकता" त्रुटि का सामना कर रहा हूं जिसे मैं समझ नहीं सकता।यह हास्केल कोड "अनंत प्रकार" त्रुटि का उत्पादन क्यों करता है?

असल में, इससे परे, मैं इस त्रुटि का क्या अर्थ है, इस बारे में अच्छी व्याख्या नहीं पा रहा हूं, इसलिए यदि आप मेरे मूल प्रश्न से परे जा सकते हैं और "अनंत प्रकार" त्रुटि की व्याख्या कर सकते हैं, तो मैं वास्तव में सराहना करता हूं यह।

कोड यह रहा:

intersperse :: a -> [[a]] -> [a] 

-- intersperse '*' ["foo","bar","baz","quux"] 
-- should produce the following: 
-- "foo*bar*baz*quux" 

-- intersperse -99 [ [1,2,3],[4,5,6],[7,8,9]] 
-- should produce the following: 
-- [1,2,3,-99,4,5,6,-99,7,8,9] 

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:y:xs) = x:s:y:intersperse s xs 

और यहाँ दुभाषिया में लोड करने का प्रयास त्रुटि है:

Prelude> :load ./chapter.3.ending.real.world.haskell.exercises.hs 
[1 of 1] Compiling Main (chapter.3.ending.real.world.haskell.exercises.hs, interpreted) 

chapter.3.ending.real.world.haskell.exercises.hs:147:0: 
Occurs check: cannot construct the infinite type: a = [a] 
When generalising the type(s) for `intersperse' 
Failed, modules loaded: none. 

धन्यवाद।

सही कोड

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:xs) = x ++ s:intersperse s xs 

क्या: -

यहाँ कुछ कोड और हास्केल में "अनंत प्रकार" त्रुटि से निपटने के लिए एक सामान्य दिशानिर्देश को सही है समस्या थी:

मेरा प्रकार हस्ताक्षर राज्य एस है कि intersperse का दूसरा पैरामीटर सूचियों की सूची है। इसलिए, जब मैं "एस (एक्स: वाई: एक्सएस)" के खिलाफ मिलान करता हूं, तो एक्स और वाई सूचीबद्ध करता है। और फिर भी मैं x और y को तत्वों के रूप में देख रहा था, सूची नहीं। "अनंत प्रकार" त्रुटि से निपटने के लिए

दिशानिर्देश:

अधिकांश समय, जब आप इस त्रुटि मिलती है, आप विभिन्न चर आप साथ काम कर रहे के प्रकार को भूल गए हैं, और आप एक चर का उपयोग करने का प्रयास किया है जैसे कि यह किसी अन्य प्रकार की तुलना में था। ध्यान से देखें कि किस प्रकार का सब कुछ बनाम है कि आप इसका उपयोग कैसे कर रहे हैं, और यह आमतौर पर समस्या को उजागर करेगा।

+1

एक और अच्छी युक्ति: प्रकारों को स्पष्ट रूप से घोषित करें। यह संकलक को जांचने के लिए कुछ देता है। –

+1

तो यह समस्या हल करता है, लेकिन संकलक क्यों कहते हैं "अनंत प्रकार का निर्माण नहीं कर सकता?"। इसका क्या मतलब है? यदि समस्या यह है कि आप उन परिचालनों का संचालन करने की कोशिश कर रहे हैं जो उन परिचालनों का समर्थन नहीं करते हैं, तो संकलक ऐसा कुछ क्यों नहीं कहता है? प्रश्न की संरचना के लिए – freedrull

+9

+1 (प्रश्न - सही - समस्या थी - दिशानिर्देश) – Dacav

उत्तर

27

समस्या अंतिम खंड में है, जहां आप एक्स और वाई तत्वों के रूप में व्यवहार करते हैं, जबकि वे सूचियां हैं। यह काम करेगा:

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:y:xs) = x ++ [s] ++ y ++ intersperse s xs 

अनंत प्रकार की त्रुटि होती है क्योंकि: ऑपरेटर टाइप है एक -> [एक] -> [एक], आप मानते हैं, जबकि [एक] -> एक -> [एक] , जिसका अर्थ है कि [ए] को एक के साथ पहचाना जाना चाहिए, जिसका अर्थ यह होगा कि एक असीम घोंसला वाली सूची है। इसकी अनुमति नहीं है (और आप क्या मतलब है, वैसे भी)।

संपादित करें: उपरोक्त कोड में एक और बग भी है। यह होना चाहिए:

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:xs) = x ++ [s] ++ intersperse s xs 
+0

धन्यवाद। मैंने उन दोनों को बाहर निकाला और फिर यहां वापस आये और आपकी प्रतिक्रिया देखी, जो मेरे लिए उत्कृष्ट सत्यापन था। आपने मेरी बग को भी बेहतर से ठीक किया है। मेरी बग यह थी कि यह वाई और एक्स के बीच विभाजक को छोड़ रहा था। इसे ठीक करने के लिए, मैंने पैटर्न मिलान के एक और स्तर को पेश किया, जैसे: intersperse (x: y: []) = x ++ s: y intersperse (x: y: xs) = intersperse [x, वाई] ++ एस: intersperse xs लेकिन ऐसा लगता है कि आपने उस अतिरिक्त स्तर की आवश्यकता के बिना मेरी बग तय की है। –

+1

यह सबक है जो मैं सीखता हूं: "एक 'अनंत प्रकार' त्रुटि का सामना करते समय, आप शायद भूल रहे हैं कि आप किस प्रकार से काम कर रहे हैं और इसलिए ऐसा कुछ कर रहे हैं जिसका आप मतलब नहीं था। ध्यान से देखें कि आपका प्रत्येक प्रकार किस प्रकार है चर है, और यह आमतौर पर समस्या को उजागर करेगा। " क्या आप इसमें कुछ भी जोड़ या बदलना चाहते हैं? –

+0

यह निश्चित रूप से सही है, और मैं इसमें कुछ भी नहीं बदलूंगा।अनंत प्रकारों की अनुमति नहीं है, और इसलिए एक अनंत प्रकार त्रुटि का अर्थ है कि कहीं भी किसी फ़ंक्शन को गलत प्रकार के साथ तर्क प्राप्त होता है। आरडब्ल्यूएच के साथ शुभकामनाएँ :) – Stephan202

2

मैं गलत हो सकता हूं, लेकिन ऐसा लगता है कि आप एक और कठिन समस्या को हल करने की कोशिश कर रहे हैं। intersperse का आपका संस्करण केवल सरणी के साथ मान को छेड़छाड़ नहीं करता है, बल्कि यह एक स्तर को भी फ़्लैट करता है।

List हास्केल में मॉड्यूल वास्तव में एक अंतरण समारोह प्रदान करता है। यह सूची में प्रत्येक तत्व के बीच दिए गए मान में डालता है।उदाहरण के लिए:

intersperse 11 [1, 3, 5, 7, 9] = [1, 11, 3, 11, 5, 11, 7, 11, 9] 
intersperse "*" ["foo","bar","baz","quux"] = ["foo", "*", "bar", "*", "baz", "*", "quux"] 

मैं यह सोचते कर रहा हूँ यह है कि क्या तुम मेरे प्रोफेसर हमें जब मैं हास्केल सीख रही थी करना चाहता था क्या है, क्योंकि यह करने के लिए चाहते हैं। मैं, ज़ाहिर है, पूरी तरह से बाहर हो सकता है।

+0

टिप्पणी के लिए धन्यवाद। इस मामले में, हालांकि, मैं इसे एक स्तर को फ़्लैट करना चाहता हूं, क्योंकि मैं "रियल वर्ल्ड हास्केल" के अध्याय 3 के अंत से अभ्यास 7 कर रहा हूं। –

+0

गोचा। अगर मेरे पास किताब थी, तो मैंने लिखा था इससे पहले मैंने जांच की होगी। हां, मैं बस इतना अनुमान लगा सकता था। खुशी है कि आप इसे किसी भी तरह हल किया गया है। :-) –

+4

पुस्तक की सामग्री को ऑनलाइन उपलब्ध कराया गया है: http://book.realworldhaskell.org/ – Stephan202

0

इसके अलावा मुझे this मिला जो त्रुटि का अर्थ बताता है।

हर बार दुभाषिया/कंपाइलर मुझे यह त्रुटि देता है क्योंकि यह औपचारिक पैरामीटर के रूप में कुछ प्रकार-parametrized tuple का उपयोग कर रहा है। सब कुछ द्वारा सही ढंग से काम करता है फ़ंक्शन की प्रकार परिभाषा को हटाता है, जिसमें प्रकार चर शामिल थे।

मैं अभी भी यह नहीं समझ सकता कि इसे कैसे ठीक किया जाए और फ़ंक्शन प्रकार परिभाषा को कैसे रखा जाए।

3

अक्सर एक स्पष्ट प्रकार परिभाषा जोड़ना संकलक के प्रकार त्रुटि संदेश को और अधिक समझ में डाल सकता है। लेकिन इस मामले में, स्पष्ट टाइपिंग संकलक के त्रुटि संदेश को और खराब बनाती है।

देखो क्या होता है जब मैं GHC बिखेरना के प्रकार लगता है:

Occurs check: cannot construct the infinite type: a = [a] 
    Expected type: [a] -> [[a]] -> [[a]] 
    Inferred type: [a] -> [[a]] -> [a] 
In the second argument of `(:)', namely `intersperse s xs' 
In the second argument of `(:)', namely `y : intersperse s xs' 

कि स्पष्ट रूप से कोड में बग की ओर संकेत करता है। इस तकनीक का उपयोग करने के लिए आपको सबकुछ पर नजर रखने और प्रकारों के बारे में कठिन सोचने की ज़रूरत नहीं है, जैसा कि अन्य ने सुझाव दिया है।

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