2011-12-17 19 views
20

मैं Learn You a Haskell for Great Good! पुस्तक से YesNo उदाहरण के माध्यम से जाने का प्रयास कर रहा हूं।बाधाओं में अस्पष्ट प्रकार परिवर्तनीय 'a0'

module Main where 

main :: IO() 

main = putStrLn (show (yesno 12)) 

class YesNo a where 
    yesno :: a -> Bool 


instance YesNo Bool where 
    yesno b = b 

instance YesNo [a] where 
    yesno [] = False 
    yesno _ = True 


instance YesNo Int where 
    yesno 0 = False 
    yesno _ = True 

जब मैं निष्पादित इस कोड को निम्नलिखित अपवाद तब होता है:

Ambiguous type variable `a0' in the constraints: 
    (YesNo a0) arising from a use of `yesno' 
      at /Users/mkhadikov/Projects/personal/haskell/hello-world/yesno.hs:5:25-29 
    (Num a0) arising from the literal `12' 
      at /Users/mkhadikov/Projects/personal/haskell/hello-world/yesno.hs:5:31-32 
Probable fix: add a type signature that fixes these type variable(s) 
In the first argument of `show', namely `(yesno 12)' 
In the first argument of `putStrLn', namely `(show (yesno 12))' 
In the expression: putStrLn (show (yesno 12)) 

आप कृपया समझा सकते हैं कि इस कोड के साथ गलत क्या है

यहाँ मेरी स्रोत कोड है?

उत्तर

31

समस्या यह है कि यह नहीं जानता कि 12 प्रकार क्या है! यह एक अंक उदाहरण के साथ किसी भी प्रकार हो सकता है:

आप प्रकार आप सीधे चाहते हैं निर्दिष्ट करने की आवश्यकता: putStrLn (show (yesno (12 :: Int))) प्रयास करें।

जीएचसी क्यों नहीं चुन सकता है, क्योंकि कोई अन्य विकल्प काम नहीं करेगा, आप पूछते हैं? अच्छा प्रश्न। जवाब यह है कि हास्केल के टाइपक्लास सिस्टम के साथ, एक उदाहरण जोड़ना मौजूदा सही प्रोग्रामों को कभी भी अमान्य नहीं कर सकता या उनके व्यवहार को बदल नहीं सकता है। (इसे खुली दुनिया धारणा के रूप में जाना जाता है।) यदि यह Int चुनता है, तो क्या होगा यदि आपने instance YesNo Integer जोड़ा? पसंद संदिग्ध हो जाएगा, और आपका कार्यक्रम तोड़ देगा!

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

5

समस्या यह है कि 12 वास्तव में Num a => a टाइप करें और Int जैसा कि आप उम्मीद करते हैं। यदि आप एक स्पष्ट प्रकार एनोटेशन जैसे 12 :: Int जोड़ते हैं, तो इसे संकलित करना चाहिए।

+0

यह डेटा कंस्ट्रक्टर्स कि हास्केल में '12' की तरह काम की अपनी तरह बनाने के लिए संभव है? ऐसा लगता है कि जब भी आप एक डेटा कंस्ट्रक्टर बनाते हैं, तो यह एक प्रकार का मान बनाता है। लेकिन जब आप '12' लिखते हैं, जैसा कि आप देख सकते हैं कि यह एक प्रकार का मान नहीं है, लेकिन किसी भी प्रकार का मान जहां संख्या नम द्वारा बाधित है। इस प्रकार 'संख्या एक => ए'। क्या मैं इसे सही तरीके से समझ रहा हूं? क्या इस तरह का एक मूल्य बनाने की तरह है जिसमें अस्तित्व/संघ है? – CMCDragonkai

+0

@CMCDragonkai मैं विवरण पर थोड़ा अस्पष्ट हूं लेकिन मूल रूप से टाइपक्लास 'न्यू' में एक फ़ंक्शन 'इंटेगर :: न्यू ए => इंटीजर -> ए' है। एक संख्यात्मक शाब्दिक काम जैसे कि 'से इंटेगर' को बुलाया गया था। – fuz

+0

आह, इसलिए 'ए' एक अस्तित्व/संघ बन गया है। बहुत ही रोचक। – CMCDragonkai

1

मुझे एक ही समस्या थी।

यह एक समाधान शायद सबसे अच्छा एक नहीं है, लेकिन यह काम करता है:

class YesNo a where 
    yesno :: a -> Bool 


instance YesNo Int where 
    yesno 0 = False 
    yesno _ = True 


instance YesNo Integer where 
    yesno 0 = False 
    yesno _ = True 
संबंधित मुद्दे