2012-04-29 11 views
13

प्रश्न 1हास्केल: GHCi में त्रुटि संदेश "के लिए कोई उदाहरण" समझने

हाय, अगर WinGHCi में मैं जानबूझकर कोड की निम्न गलत टुकड़ा कर: तब त्रुटि संदेश

3 4 

मैं मिल रहा है

<interactive>:1:1: 
    No instance for (Num (a0 -> t0)) 
     arising from the literal `3' 
    Possible fix: add an instance declaration for (Num (a0 -> t0)) 
    In the expression: 3 
    In the expression: 3 4 
    In an equation for `it': it = 3 4 

वास्तव में क्या No instance for (Num (a0 -> t0)) मतलब है?

प्रश्न 2

क्यों कोड का निम्न भाग:

(+) 2 3 4 
<interactive>:1:7: 
    No instance for (Num (a0 -> t0)) 
     arising from the literal `3' 
    Possible fix: add an instance declaration for (Num (a0 -> t0)) 
    In the second argument of `(+)', namely `3' 
    In the expression: (+) 2 3 4 
    In an equation for `it': it = (+) 2 3 4 

उपज कोड के दूसरे टुकड़े से एक अलग त्रुटि:

2+3 4 
<interactive>:1:3: 
    No instance for (Num (a1 -> a0)) 
     arising from the literal `3' 
    Possible fix: add an instance declaration for (Num (a1 -> a0)) 
    In the expression: 3 
    In the second argument of `(+)', namely `3 4' 
    In the expression: 2 + 3 4 
अर्थात् पहले में

कोड का टुकड़ा हमारे पास No instance for (Num (a0 -> t0)) है जहां कोड के दूसरे भाग में हमारे पास No instance for (Num (a1 -> a0)) है।


[रिस्पांस ehird करने के लिए]

(सवालों का जवाब टिप्पणियों से ले जाया गया):

1) मैं सराहना बाद के दो भाव अलग-अलग हैं, लेकिन आप कह रहे हैं कि मैं समझने की कोशिश नहीं करनी चाहिए पूर्ववर्ती के लिए पूर्व और (Num(a1 -> a0)) के लिए दुभाषिया (Num (a0 -> t0)) क्यों चुनता है, इस तथ्य के अलावा कि वे अलग हैं?

2) हाय, और पूर्व के साथ जब आप कहते हैं "लेकिन कार्यों के लिए कोई संख्या उदाहरण नहीं है" तो आपका क्या मतलब है? क्षमा करें मैं इस बात पर स्पष्ट नहीं हूं कि एक उदाहरण की अवधारणा क्या है। इसके अलावा, जिज्ञासा से बाहर, क्या आप अपने उदाहरण Num (a -> b) विधि का उपयोग किसी भी तरह दुभाषिया को 3 4 को 4 modulo 3 के रूप में समझने के लिए बता सकते हैं?

उत्तर

16

मेरा इरादा थोड़ा और स्पष्टीकरण के साथ एहर्ड के उत्तर को पूरक करना है।जब आप अभिव्यक्ति

3 4 

लिखा था तब हास्केल दुभाषिया सोचता है कि आप जो कुछ भी 4 है समारोह 3 लागू करने के लिए कोशिश कर रहे हैं। आदेश हास्केल एक समारोह के रूप 3 व्याख्या करने के लिए के लिए में, यह आदेश एक समारोह पूर्णांक 3 से (अर्थात प्रकार a -> b के बारे में कुछ) प्राप्त करने के लिए समारोह

fromInteger :: Integer -> (a -> b) 

करने के लिए एक कॉल करने के लिए की जरूरत है। अब, fromInteger जब आप प्रकार xNum वर्ग का एक उदाहरण बनाने के हस्ताक्षर

instance Num x where 
    fromInteger :: Integer -> x 

यानी के लिए Num typeclass में परिभाषित किया गया है, आप कैसे में एक पूर्णांक शाब्दिक कन्वर्ट करने के लिए fromInteger के एक कार्यान्वयन जो हास्केल बताता देना एक x। आपके मामले में, x फ़ंक्शन प्रकार a -> b है। तो ये करते है!


पहला, कुछ बॉयलरप्लेट। x बनाने के Num हास्केल का एक उदाहरण है कि हम भी यह Show और Eq का एक उदाहरण बनाने की आवश्यकता है:

instance Show (a -> b) where show f = "<function>" 
instance Eq (a -> b) where f == g = False 

अब मान लीजिए कि हम के रूप में "4 सापेक्ष 3" 3 4 व्याख्या करने के लिए चाहते हैं। फिर हमें mod पर कॉल करने वाले फ़ंक्शन के रूप में किसी भी पूर्णांक की व्याख्या करने के लिए हास्केल को बताने की आवश्यकता है। इसके अलावा, के बाद से mod केवल अभिन्न प्रकार स्वीकार करता है (यह हस्ताक्षर mod :: Integral a => a -> a -> a है) तो हम a और b के प्रकारों को प्रतिबंधित करने के साथ ही अभिन्न होने की जरूरत:

instance (Integral a, Integral b) => Num (a -> b) where 

make an instance of Num करने के लिए हम (+) के कार्यान्वयन देने के लिए, (-) की जरूरत , (*) और fromIntegral (वास्तव में हमें कुछ अन्य कार्यों को भी परिभाषित करना चाहिए, लेकिन अब इसके बारे में चिंता न करें)।

एक काफी प्राकृतिक जब आप दो कार्यों को जोड़ने के अलावा, घटाव और गुणा (यहां से सभी कोड Num उदाहरण का एक हिस्सा है और उदाहरण घोषणा के सापेक्ष इंडेंट किया जाना चाहिए)

f + g = \x -> f x + g x 
    f - g = \x -> f x - g x 
    f * g = \x -> f x * g x 

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

एक समारोह के रूप में एक पूर्णांक हम

fromInteger n = \m -> fromIntegral m `mod` fromIntegral n 

यानी लिख सकते हैं जब हम एक पूर्णांक n है व्याख्या करने के लिए, हम एक पैरामीटर m है कि, जब कहा जाता है, यह सुनिश्चित करता है के एक समारोह लौटने कि दोनों बहस ही के हैं टाइप करें (fromIntegral दोनों को कॉल करके) और फिर उन्हें mod फ़ंक्शन के लिए तर्क के रूप में उपयोग करता है।

अंत में, एक थोड़ा और अधिक बॉयलरप्लेट शिकायत हास्केल को रोकने के लिए:

abs f = undefined 
    signum f = undefined 

हम इस परीक्षण कर सकते हैं। मेरे पास numfun.hs नामक फ़ाइल में मेरा कोड है। मैं हास्केल दुभाषिया बूट और मेरे फ़ाइल लोड:

Prelude> :l numfun.hs 
[1 of 1] Compiling Main    (numfun.hs, interpreted) 
Ok, modules loaded: Main. 

अब मैं कुछ कार्यों को परिभाषित कर सकते हैं:

*Main> let f = (+ 1) 
*Main> let g = (* 2) 

मैं उन्हें जोड़ सकते हैं या उन्हें घटाना:

*Main> (f + g) 3 -- (3+1) + (3*2) 
10 
*Main> (f - g) 3 -- (3+1) - (3*2) 
-2 

और मैं कर सकते हैं कार्यों के रूप में कॉल नंबर:

*Main> 3 4   -- 4 `mod` 3 
1 
+0

वाह इस विस्तृत और अच्छी तरह से उल्लिखित स्पष्टीकरण के लिए आपको बहुत बहुत धन्यवाद; मैं वास्तव में इसकी प्रशंसा करता हूँ। मुझे लगता है कि मुझे हास्केल वेबसाइट पर निर्दिष्ट कुछ पुस्तकों को हिट करने की आवश्यकता होगी और आपके द्वारा लिखे गए सब कुछ को पचाने से पहले कुछ और बार अपनी पोस्ट पर लौटना होगा। धन्यवाद। – artella

14

पहली त्रुटि होती है क्योंकि 4 जैसे एक पूर्णांक अक्षर Num उदाहरण के साथ किसी भी प्रकार का हो सकता है। यही है, 4 प्रकार (Num a) => a है, इसलिए यह (एक Integer, एक Double, एक Rational, आदि जब से तुम एक तर्क (4), यह जानता है कि, के संदर्भ में, 3 एक समारोह प्रकार होना चाहिए करने के लिए 3 लागू के रूप में सेवा कर सकते हैं यानी a0 -> t0 कुछ a0 और t0) के लिए। लेकिन फ़ंक्शन के लिए Num उदाहरण नहीं है, इसलिए फ़ंक्शन के रूप में का उपयोग अमान्य है। यदि आपने instance Num (a -> b) जोड़ा है, तो यह काम करेगा, लेकिन आप शायद नहीं चाहते हैं।

बाद के लिए, दो त्रुटि संदेश समकक्ष हैं; जीएचसी द्वारा उत्पन्न नामों का कोई विशेष अर्थ नहीं है। अक्षरों को आम तौर पर आपके द्वारा उपयोग किए जा रहे कार्यों के प्रकारों में प्रकार चर से प्राप्त किया जाता है, और संख्याओं को अनजान रखने के लिए संख्याओं को जोड़ा जाता है। इस मामले में, दूसरी अभिव्यक्ति (+) 2 (3 4) के बराबर है (क्योंकि फ़ंक्शन एप्लिकेशन किसी भी इंफिक्स ऑपरेटर से अधिक कठिन होता है), जो आपके कोड के पहले भाग के समान नहीं है।

+0

हाय, मैं सराहना करता हूं बाद में दो अभिव्यक्तियां अलग-अलग हैं, लेकिन क्या आप कह रहे हैं कि मुझे यह समझने की कोशिश नहीं करनी चाहिए कि क्यों दुभाषिया पूर्व के लिए '(संख्या (ए0 -> टी 0)) चुनता है और '(न्यू (ए 1 -> ए0))' के लिए उत्तरार्द्ध, इस तथ्य के अलावा कि वे अलग हैं? धन्यवाद। – artella

+0

हाय, और पूर्व के साथ जब आप कहते हैं "लेकिन कार्यों के लिए कोई संख्या उदाहरण नहीं है" आपका क्या मतलब है? क्षमा करें मैं इस बात पर स्पष्ट नहीं हूं कि एक उदाहरण की अवधारणा क्या है। इसके अलावा, जिज्ञासा से बाहर, क्या आप अपने 'इंस्टेंस न्यूम (ए -> बी)' विधि का उपयोग किसी भी तरह से दुभाषिया को '4 4'' को '4 मॉड्यूलो 3' के रूप में समझने के लिए कह सकते हैं? धन्यवाद – artella

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