2015-07-19 10 views
10

GHCi में कुछ अभ्यास करते समय मैं टाइप किया और निम्नलिखित>साथ प्रकार अंक अजीब हास्केल अभिव्यक्ति ([चार] -> टी) => टी

ghci> (1 "one") 

<interactive>:187:1: 
    No instance for (Num ([Char] -> a0)) arising from a use of ‘it’ 
    In a stmt of an interactive GHCi command: print it 

जो गलती से हुआ है मिला है, Howeve अगर मैं GHCi पूछना

ghci> :type (1 "one") 
(1 "one") :: Num ([Char] -> t) => t 

(1 "one") का अर्थ क्या है: अभिव्यक्ति के प्रकार के लिए यह किसी भी त्रुटि नहीं करता है?

यह अभिव्यक्ति एक त्रुटि क्यों देती है, लेकिन जीएचसीआई बताता है कि यह अच्छी तरह टाइप किया गया है?

Num ([Char] -> t) => t का अर्थ क्या है?

धन्यवाद।

+1

याद रखें कि स्थान फ़ंक्शन एप्लिकेशन ऑपरेटर है। – Bergi

उत्तर

10

बचाव के लिए हास्केल रिपोर्ट! (section 6.4.1 का हवाला देते हुए)

An integer literal represents the application of the function fromInteger to the appropriate value of type Integer.

fromInteger टाइप है:

Prelude> :t fromInteger 
fromInteger :: Num a => Integer -> a 

तो 1 वास्तव में fromInteger (1 :: Integer) के लिए वाक्यविन्यास चीनी है। आपका अभिव्यक्ति है, तो, यह है:

fromInteger 1 "one" 

कौन सा लिखा जा सकता है के रूप में:

(fromInteger 1) "one" 

अब, fromInteger एक नंबर (जो एक प्रकार है जो Num का एक उदाहरण है की एक मूल्य के रूप में है, का उत्पादन इसका प्रकार हमें बताता है)। आपकी अभिव्यक्ति में, यह संख्या [Char] (स्ट्रिंग "one") पर लागू होती है।

Num ([Char] -> t) => t 

है यही कारण है, यह परिणाम होगा एक समारोह जो भी एक [Char] करने के लिए एक Num है लागू करने के (अनिर्दिष्ट प्रकार t की): GHC सही तरीके से अपने अभिव्यक्ति टाइप है कि निकालना जानकारी के इन दो टुकड़े को जोड़ती है। यह सिद्धांत में एक वैध प्रकार है। एकमात्र समस्या यह है कि Num[Char] -> t के लिए कोई उदाहरण नहीं है (यानी, स्ट्रिंग्स लेने वाले फ़ंक्शंस संख्याएं नहीं हैं, जो आश्चर्यजनक नहीं हैं)।

पीएस .: जैसा कि सिबी और Ørjan इंगित करते हैं, जीएचसी 7.10 में और बाद में आपको केवल प्रश्न में उल्लिखित त्रुटि दिखाई देगी यदि FlexibleContexts जीएचसी एक्सटेंशन सक्षम है; अन्यथा टाइप चेकर क्लास बाधा (यानी, Char, [] और (->)) में निश्चित प्रकार और प्रकार के कन्स्ट्रक्टर रखने के बारे में शिकायत करेगा।

+1

अच्छा जवाब। साथ ही, यदि आप 'ghci' में टाइप चेक करना चाहते हैं, तो इसे' फ्लेक्सिबल कॉन्टैक्स 'संदर्भ एक्सटेंशन को सक्षम करके बनाया जा सकता है। 'x = 1 "एक" 'और': t x' आपको एक ही प्रकार को' ghci' में दिखाएगा। – Sibi

+0

मुझे नहीं लगता कि सवाल यह मान रहा है कि 'फ्लेक्सिबल कॉन्टैक्स' जीएचसी एक्सटेंशन सक्षम है। प्रकार ': टी (1" एक ")' उस एक्सटेंशन को सक्षम किए बिना काम करता है जो ghci आईएमओ का एक सतत व्यवहार नहीं है। – Sibi

+0

@ सिबी वास्तव में। फिर भी, यदि आप 'फ्लेक्सिबल कॉन्टैक्स' सक्षम नहीं करते हैं तो 't'' के बिना त्रुटि बदलती है। – duplode

1

टीएल; डीआर: यह एक गंदे बकवास प्रकार है जो चिंतित होने के लायक नहीं है।

इंटीजर अक्षर किसी भी प्रकार के मानों का प्रतिनिधित्व कर सकते हैं जो Num टाइपक्लास लागू करता है। तो 1 या किसी भी अन्य पूर्णांक अक्षर का उपयोग कहीं भी आपको एक संख्या की आवश्यकता हो सकती है।

doubleVal :: Double 
doubleVal = 1 

intVal :: Int 
intVal = 1 

integerVal :: Integer 
integerVal = 1 

इससे हमें किसी भी संख्यात्मक संदर्भ में अभिन्न अंगों का उपयोग करने में सक्षम बनाता है।

जब आप किसी भी प्रकार के संदर्भ के बिना एक पूर्णांक शाब्दिक का उपयोग करते हैं, तो ghci नहीं जानता कि यह किस प्रकार है।

Prelude> :type 1 
1 :: Num a => a 

GHCi कह रहा है "कि '1' कुछ प्रकार मैं नहीं जानता कि की है, लेकिन मुझे पता है कि यह है जो भी प्रकार, उस प्रकार लागू करता Num typeclass है"।

हास्केल स्रोत में एक पूर्णांक अक्षरक की प्रत्येक घटना को एक अंतर्निहित fromInteger फ़ंक्शन के साथ लपेटा गया है। तो (1 "one") को ((fromInteger (1::Integer)) "one") में निहित रूपांतरित कर दिया गया है, और उप-संपीड़न (fromInteger (1::Integer)) में अभी तक अज्ञात प्रकार Num a => a है, जिसका अर्थ है कि यह कुछ अज्ञात प्रकार है, लेकिन हम जानते हैं कि यह Num टाइपक्लास का उदाहरण प्रदान करता है।

हम यह भी देख सकते हैं कि यह "one" करने के लिए एक समारोह की तरह लागू किया जाता है, इसलिए हम जानते हैं कि अपने प्रकार प्रपत्र [Char] -> a0 जहां a0 अभी तक एक अज्ञात प्रकार है होना आवश्यक है। तो a और [Char] -> a0 समान होना चाहिए। Num a => a प्रकार में हमने उपरोक्त अनुमान लगाया है, हम जानते हैं कि 1 में Num ([Char] -> a0) => [Char] -> a0) टाइप होना चाहिए, और अभिव्यक्ति (1 "one") में Num ([Char] -> a0) => a0 है। कि पिछले प्रकार पढ़ें "के रूप में कुछ प्रकार a0 जो एक समारोह के लिए एक [Char] तर्क लागू करने का परिणाम है नहीं है, और कहा कि समारोह प्रकार Num वर्ग का एक उदाहरण है।

तो अभिव्यक्ति ही एक मान्य प्रकार Num ([Char] -> a0) => a0 है।

हास्केल को Monomorphism restriction कहा जाता है। इसका एक पहलू यह है कि अभिव्यक्तियों में सभी प्रकार के चर के पास एक विशिष्ट, ज्ञात प्रकार होना चाहिए, इससे पहले कि आप उनका मूल्यांकन कर सकें। जीएचसी कुछ स्थितियों में डिफॉल्ट नियमों का उपयोग करता है, जब यह समायोजित हो सकता है monomorphism प्रतिबंध। हालांकि, जीएचसी किसी भी प्रकार a0 के बारे में नहीं जानता है, यह उपरोक्त प्रकार अभिव्यक्ति में प्लग कर सकता है जिसमें Num उदाहरण परिभाषित किया गया है। इसलिए मैं टी के साथ सौदा करने का कोई तरीका नहीं है, और आपको "नो इंस्टेंट फॉर न्यूम ..." संदेश देता है।

+1

यह निश्चित रूप से * नहीं * एक 'गड़बड़ बकवास प्रकार' है। आप क्यों कहते हैं कि आपके टीएल में; डॉ? – AJFarmar

+0

क्या आप इस प्रकार को उपयोगी और सार्थक मानते हैं? – NovaDenizen

+0

@ नोवाडेनज़ेन हां! उदाहरण के लिए, मेरा उत्तर यहां देखें - http://stackoverflow.com/questions/32443925/haskell-weird-expression/32444024#32444024 –

3

हास्केल एक बहुत ही लचीली भाषा है, लेकिन एक बहुत ही तार्किक एक शाब्दिक अर्थ में एक है। अक्सर, ज्यादातर भाषाओं में जो चीजें सिंटैक्स त्रुटियां होंगी, हास्केल उन्हें देखेंगे और उनको समझने के लिए अपने सबसे कठिन प्रयास करेंगे, जो परिणाम वास्तव में उलझन में हैं लेकिन वास्तव में भाषा के नियमों का तार्किक परिणाम हैं।

उदाहरण के लिए, अगर हम अजगर में अपने उदाहरण टाइप करें, यह मूल रूप से हमें बताता है "क्या तुम सिर्फ में टाइप शून्य समझ में आता है":

irb(main):001:0> (1 "one") 
SyntaxError: (irb):1: syntax error, unexpected tSTRING_BEG, expecting ')' 
(1 "one") 
    ^
    from /usr/bin/irb:12:in `<main>' 

:

Python 2.7.6 (default, Sep 9 2014, 15:04:36) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> (1 "one") 
    File "<stdin>", line 1 
    (1 "one") 
     ^
SyntaxError: invalid syntax 

रूबी एक ही बात करता है लेकिन हास्केल आसानी से हार नहीं मानता है! यह (1 "one") देखता है, और यह कारण है कि:

रूप f x की
  • भाव समारोह अनुप्रयोगों कर रहे हैं, जहां fa -> b की तरह टाइप किया है, x टाइप a है और f x टाइप b है।
  • तो अभिव्यक्ति में 1 "one", 1 एक ऐसा कार्य होना चाहिए जो "one" ([Char]) को इसके तर्क के रूप में लेना चाहिए।

फिर सांख्यिक शाब्दिक की हास्केल के उपचार दिया, यह fromInteger 1 :: Num b => [Char] -> b में 1 अनुवाद करता है। fromIntegerNum वर्ग का एक तरीका है, जिसका अर्थ है कि उपयोगकर्ता को किसी भी प्रकार के लिए अपने स्वयं के कार्यान्वयन की अनुमति है- [Char] -> b यदि आप इतने इच्छुक हैं।

तो त्रुटि संदेश का अर्थ है कि हास्केल, आपको यह बताने की बजाय कि आपने जो लिखा है वह बकवास है, आपको बताता है कि आपने इसे Num b => [Char] -> b के प्रकार का निर्माण करने के तरीके को सिखाया नहीं है, क्योंकि यह वास्तव में अजीब चीज़ है जिसे आवश्यकता होगी अभिव्यक्ति के लिए अभिव्यक्ति के लिए सच होना।

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