2012-12-30 8 views
5
toFloat :: (Floating a) => String -> a 
toFloat s = read s :: Float 

main = print (toFloat "1") 

मुझे त्रुटि देता है:हास्केल Typeclasses (फ्लोट फ्लोटिंग संकेत नहीं करता?)

Could not deduce (a ~ Float) 
from the context (Floating a) 

मुझे यकीन है कि मैं कुछ बुनियादी याद कर रहा हूँ कर रहा हूँ, लेकिन ऐसा लगता है जैसे मेरी toFloat हमेशा एक फ्लोट लौटना चाहिए और वह फ्लोट फ़्लोटिंग का मतलब होना चाहिए।

उत्तर

18

प्रकार हस्ताक्षर परिणाम का वादा किया Floating वर्ग कॉलर चाहता है के किसी भी मामले हो जाएगा कुछ करना होगा क्या। कार्यान्वयन कहता है, "क्या पता है? उस वादे पर कभी न मानें कि यह किसी भी प्रकार का हो सकता है - आइए बस इसे Float बनाएं"।

तब संकलक साथ आता है और कहता है "वाह! आप जिस प्रकार से वादा किया था वह वापस नहीं लौट रहे हैं।" सिवाय इसके कि यह आपके प्रकार के हस्ताक्षर और आपके कार्यान्वयन के लिए वास्तव में कठिन प्रयास करने की कोशिश की। उसने खुद से कहा "अगर यह किसी भी तरह से बाधित था, तो a हमेशा Float जैसा ही था, यह सही होगा।" यह वास्तव में आपके कोड को सही तरीके से ढूंढना चाहता था। खैर, इस तरह की बाधा लिखने का तरीका ~, प्रकार समानता ऑपरेटर का उपयोग कर रहा है। (a ~ Float) की बाधा का अर्थ है "aFloat जैसा ही प्रकार है"। तो संकलक आपके द्वारा दिए गए संदर्भ को हस्ताक्षर में चेक करता है, और यह उस बाधा को खोजने में विफल रहता है। और यह आपके प्रकार के हस्ताक्षर और कार्यान्वयन को एक साथ काम करने, छोड़ने और त्रुटि की रिपोर्ट करने के तरीकों से बाहर हो जाता है।

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

+0

त्वरित प्रतिक्रिया के लिए धन्यवाद। यह मेरे लिए पूरी तरह से मुद्दे को स्पष्ट करता है। किसी भी तरह से यह मेरे लिए क्लिक नहीं किया गया कि मेरे फ़ंक्शन के कॉलर मेरे टाइपक्लास के विशिष्ट उदाहरण के लिए पूछ सकते हैं। – nottombrown

5

आप कह रहे हैं toFloatFloating टाइपक्लास से संबंधित किसी भी प्रकार को वापस कर सकता है लेकिन आप इसे Float पर प्रतिबंधित कर रहे हैं, जो गलत है। आपका फ़ंक्शन a में पॉलीमोर्फिक है, इसलिए आप Floating का उदाहरण वापस नहीं कर सकते हैं, यह सभी उदाहरणों के साथ काम करने में सक्षम होना चाहिए।

otherway आप द्वारा

toFloat :: (Read a,Floating a) => String -> a 
toFloat s = read s 

इस बात को समझ सकते हैं GHCi

*Main> :t toFloat "12.1" 
toFloat "12.1" :: (Floating a, Read a) => a 
*Main> :t (toFloat "12.1" :: Float) 
(toFloat "12.1" :: Float) :: Float 
*Main> :t (toFloat "12.1" :: Double) 
(toFloat "12.1" :: Double) :: Double 

चूंकि यह रिटर्न प्रकार Floating typeclass से संबंधित आप किसी भी प्रकार के (Floating का होता है) करने के लिए इसे बदलने के लिए सक्षम होना चाहिए में फ़ंक्शन के बाद स्पष्ट प्रकार के हस्ताक्षर प्रदान किए जाते हैं। दूसरी ओर जब आप स्पष्ट रूप से Float लौट रहे हैं तो अपने मामले को याद रखें, अब आप यह नहीं कह सकते कि मैं इस फ़ंक्शन से Double की अपेक्षा करता हूं क्योंकि यह स्पष्ट रूपांतरण के बिना नहीं हो सकता है।

एक और तरीका है समझने के लिए कैसे भयानक अपने धारणा समारोह पर विचार read

read :: Read a => String -> a 

अब यहाँ आप के अनुसार, तुम बस लौट सकते हैं सब कुछ के लिए कहते हैं कि Int क्योंकि IntRead के लिए एक उदाहरण है। अब आप समझ सकते हैं अगर आप की तरह

read "12" + (1.2 :: Double) 
1

यह आपको यह हो सकता था के रूप में सरल है:

-- The simplest.                                    
toFloat :: String -> Float 
toFloat = read 

-- More generalized.                                   
toFloat' :: (Floating a, Read a) => String -> a 
toFloat' = read 
8

यह सवाल या बहुत इसे करने के लिए कुछ इसी तरह एक नियमित आधार पर पूछा जाता है। (यह कोई शिकायत नहीं है, मैं बस यह इंगित कर रहा हूं कि आप इस से उलझन में एकमात्र व्यक्ति नहीं हैं।)

ओओ भाषा में, आप कह सकते हैं "यह फ़ंक्शन कुछ ऐसा करता है जो एक्स लागू करता है"। फ़ंक्शन वापस लौटने की तरह जो भी महसूस करता है, यह वास्तव में X.

हास्केल इस तरह काम नहीं करता है। यदि आप कहते हैं "यह फ़ंक्शन कुछ ऐसा करता है जो एक्स लागू करता है", तो फ़ंक्शन किसी भी संभावित प्रकार उत्पन्न करने में सक्षम होना चाहिए जो एक्स लागू करता है!

मुख्य अंतर यह है: ओओ भाषा में, फ़ंक्शन यह तय करता है कि किस प्रकार का रिटर्न (निर्दिष्ट बाधाओं के भीतर)। हास्केल में, कॉलर तय करता है कि किस प्रकार का रिटर्न (फिर से, निर्धारित बाधाओं के भीतर)।

एक बार जब आप इस महत्वपूर्ण अंतर को समझ लेते हैं, तो शेष काफी स्पष्ट है।

फिर से, बहुत सारे लोगों ने इस हिस्से को गलत समझा है। हमें शायद इसे ट्यूटोरियल और सामान में अधिक उल्लेख करना चाहिए, क्योंकि ऐसा लगता है कि यह एक VFAQ है ...

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