2012-02-04 12 views
7

मैंने एक हफ्ते पहले हास्केल का अध्ययन शुरू किया और एक अजीब समस्या है। मैंने एक साधारण डेटा प्रकार बनाया और इसे कंसोल में दिखाना चाहता हूं। मैंने अपने प्रकार के 2 रचनाकारों के लिए 2 फ़ंक्शन बनाए। यदि मैं 2 तर्कों के साथ एक कन्स्ट्रक्टर का उपयोग करता हूं तो संकलक फ़ंक्शन कॉल कर सकता है। लेकिन यह एक और समारोह नहीं कह सकता है जिसे 1 तर्क के साथ एक निर्माता को पकड़ना चाहिए।विभिन्न डेटा कन्स्ट्रक्टर के लिए कार्य

module Main (
    main 
) where 

data MyContainter a b = FirstVersion a b 
        | SecondVersion a 
        deriving(Show,Eq) 

showContainer (FirstVersion a b) = show b 
showContainer (SecondVersion a) = show a 

--startF = showContainer (FirstVersion 1 2) -- it works 
startF = showContainer (SecondVersion 1) -- it doesn't work 

main = putStr startF 

compilers बताता है:

Ambiguous type variable `a0' in the constraint: 
    (Show a0) arising from a use of `showMaybe' 
Probable fix: add a type signature that fixes these type variable(s) 
In the expression: showMaybe (SecondVersion 1) 
In an equation for `startF': startF = showMaybe (SecondVersion 1) 

ऐसा क्यों है कि बता करता है? मैंने सीधे (सेकेंडवर्सन 1) बनाया और समझ में नहीं आया कि कंपाइलर शोकंटनर (सेकेंडवर्सन ए) क्यों नहीं कहता है।

showContainer :: (Show a, Show b) => MyContainer a b -> String 

लेकिन जब आप SecondVersion 1 गुजरती हैं, यह पता नहीं है क्या b है, क्योंकि b के किसी भी प्रकार के लिएSecondVersion 1 काम करता है:

+0

यह एहसास करने में मदद करता है कि त्रुटि संदेश में प्रकार चर 'a0'' बी' जैसा ही है, और 'a' के साथ कुछ भी नहीं है। (संकलक बस उस नाम को चुनने के लिए हुआ क्योंकि 'शो' क्लास' ए' नाम का उपयोग करता है)। – hammar

उत्तर

9

समस्या showContainer प्रकार है कि है! जब आप FirstVersion पास करते हैं, तो यह ठीक काम करता है, क्योंकि FirstVersion में a और b दोनों शामिल हैं, इस बारे में कोई अस्पष्टता नहीं है कि उन्हें क्या होना चाहिए।

तो, के बाद से संकलक (जानते हुए भी कि आप क्या चाहते b का कोई रास्ता नहीं है, और जानते हुए भी कि b के चुनाव showContainer को प्रभावित नहीं करता का कोई रास्ता नहीं है सब के बाद, यह व्यवहार जब आप FirstVersion पारित को प्रभावित करता है, चूंकि यह के मान पर show का उपयोग करता है), यह छोड़ देता है।

है यही कारण है कि त्रुटि संदेश कह रहा है: प्रकार चर a0 अस्पष्ट है, तो मुझे बताओ कि यह क्या है एक प्रकार हस्ताक्षर जोड़ें। इस मामले में, यह कोई प्रभाव नहीं पड़ेगा कि यह क्या है, तो आप सिर्फ () के लिए सेट कर सकते हैं:

startF = showContainer (SecondVersion 1 :: MyContainer Integer()) 

आप शायद बहुत बार इस तरह त्रुटियों में नहीं चलेंगे, संदर्भ के बाद से आप में मूल्यों का उपयोग आमतौर पर इस्तेमाल होने के लिए एक विशिष्ट b को मजबूर कर देगा।

दुर्भाग्य से चुनने वाले प्रकार चर पर जीएचसी सबसे अच्छा नहीं है; यदि आपने showContainer को एक स्पष्ट प्रकार के हस्ताक्षर जैसा दिखाया है, तो यह त्रुटि संदेश में b का भी उपयोग करेगा।

+0

धन्यवाद, यह अच्छा वर्णन है) – Alexey

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