2011-11-30 18 views
5

तुच्छ समारोह परिभाषाओं निम्नलिखित के लिए:इन दो फ़ंक्शन प्रकार परिभाषाओं के बीच क्या अंतर है?

printLength1::(Num a)=>String->a 
printLength1 s = length s 


printLength2::String->Int 
printLength2 s = length s 

क्यों वे एक ही नहीं कर रहे हैं? मुझे किस स्थितियों में एक दूसरे को चुनना चाहिए?

और मुझे printLength1 के लिए यह त्रुटि प्राप्त:

Couldn't match type `a' with `Int' 
     `a' is a rigid type variable bound by 
      the type signature for rpnc :: String -> a at test.hs:20:1 
    In the return type of a call of `length' 
    In the expression: length s 
    In an equation for `rpnc': rpnc s = length s 

मैं इस त्रुटि को समझते हैं। लेकिन मैं इसे कैसे ठीक कर सकता हूं? मैंने पहले से ही कठोर प्रकार परिवर्तनीय के बारे में कुछ पोस्ट पढ़ ली हैं लेकिन अभी भी इसे ठीक करने के तरीके को समझ नहीं सका।

उत्तर

9

पहला प्रकार हस्ताक्षर अधिक सामान्य है। इसका मतलब है कि परिणाम Num हो सकता है - यह अपने रिटर्न प्रकार पर पॉलिमॉर्फिक है। तो आपके पहले फ़ंक्शन का परिणाम Int या Integer या किसी अन्य Num उदाहरण के रूप में उपयोग किया जा सकता है।

समस्या यह है कि length किसी भी Num उदाहरण के बजाय Int देता है। आप fromIntegral का उपयोग कर इसे ठीक कर सकते हैं:

printLength1 :: Num a => String -> a 
printLength1 s = fromIntegral $ length s 

ध्यान दें कि fromIntegral . length के हस्ताक्षर (ऊपर कोड की बात-मुक्त संस्करण है जो) Num c => [a] -> c है। यह आपके printLength1 फ़ंक्शन के लिए निर्दिष्ट हस्ताक्षर से मेल खाता है।

+0

धन्यवाद दोस्तों। मुझे उम्मीद है कि इस भाषा में छिपे हुए कोई और प्रश्नोत्तरी नहीं हैं। – osager

+3

@osager यह एक quirk नहीं है, यह प्रकार प्रणाली का एक बहुत ही मूल रूप से महत्वपूर्ण हिस्सा है। पॉलिमॉर्फिक प्रकार (कम से कम रैंक -1 पॉलिमॉर्फिक प्रकार) कंक्रीट प्रकारों में परिवर्तित होते हैं कि उनका उपयोग कैसे किया जाता है। यदि आप एक प्रकार का हस्ताक्षर लिखते हैं जो दावा करता है कि एक प्रकार पॉलिमॉर्फिक है, तो इसे वास्तव में * पॉलीमोर्फिक होना चाहिए। – Carl

+1

'न्यूम क्लास क्विर्क नहीं है, लेकिन आप तर्कसंगत तर्क दे सकते हैं कि 'लंबाई' की बजाय 'लंबाई' होने के कारण 'लंबाई' एक क्विर्क है। –

7

का हवाला देते हुए LearnYouAHaskell.com:

नोट: यह समारोह numLongChains का एक प्रकार :: इंट क्योंकि लंबाई एक इंट बजाय ऐतिहासिक कारणों से एक अंक एक देता है। अगर हम एक और सामान्य संख्या वापस करना चाहते थे, तो हम परिणामी लंबाई पर इंटेग्रल से इस्तेमाल कर सकते थे।

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