2013-02-23 10 views
25

GHCi 1 ++ 2 के लिए मुझे एक प्रकार दे देंगे:ghci मुझे ragequitting के बजाय "1 ++ 2" के लिए एक प्रकार क्यों देता है?

$ ghci 
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Prelude> :t 1 ++ 2 
1 ++ 2 :: Num [a] => [a] 

लेकिन यह स्पष्ट रूप से गलत है। यदि मैं इसे जांचने और मूल्यांकन करने के बजाय, इसे टाइप करने की बजाय, चीजों को सही ढंग से विफल करता हूं:

Prelude> 1 ++ 2 

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

क्या देता है?

+8

शीर्षक – Mysticial

उत्तर

25

लेकिन यह स्पष्ट रूप से गलत है।

नहीं, यह पूरी तरह से सही है।

(++) के प्रकार

(++) :: [a] -> [a] -> [a] 

है और पूर्णांक शाब्दिक के प्रकार

1 :: Num n => n 

तो प्रकार [a] है कि (++) का एक तर्क प्रकार Num n => n के साथ एकीकृत किया गया है चाहिए कि एक शाब्दिक है है,

1 ++ 2 :: Num [a] => [a] 

और यदि आपके पास Num उदाहरण के साथ एक सूची प्रकार है, तो उस अभिव्यक्ति का भी मूल्यांकन किया जा सकता है।

लेकिन, डिफ़ॉल्ट रूप से, वहाँ उपलब्ध सूची प्रकार के लिए कोई Num उदाहरण है, इसलिए जब आप इसे मूल्यांकन करने के लिए प्रयास करते हैं, GHCi कि यह [a] के लिए कोई Num उदाहरण पाता शिकायत।

उदाहरण के लिए:

Prelude> instance Num a => Num [a] where fromInteger n = Data.List.genericReplicate n 1 

<interactive>:2:10: Warning: 
    No explicit method or default declaration for `+' 
    In the instance declaration for `Num [a]' 

<interactive>:2:10: Warning: 
    No explicit method or default declaration for `*' 
    In the instance declaration for `Num [a]' 

<interactive>:2:10: Warning: 
    No explicit method or default declaration for `abs' 
    In the instance declaration for `Num [a]' 

<interactive>:2:10: Warning: 
    No explicit method or default declaration for `signum' 
    In the instance declaration for `Num [a]' 
Prelude> 1 ++ 2 :: [Int] 
[1,1,1] 
+0

शीर्षक के लिए +1 तो क्या इसका मतलब है कि ghci पूरी तरह अभिव्यक्ति की जांच नहीं कर रहा है? घी द्वारा नम [ए] से जाने के लिए क्या कदम नहीं उठाया जा रहा है "कोई संख्या [ए] नहीं है?" – Dave

+3

यह अनुमान लगाता है (और जांचता है) जहां तक ​​अनुमान लगाया जा सकता है। यह नहीं करता है कि यह जांच कर रहा है कि वर्तमान में स्कोप में मौजूद उदाहरण प्रकार चर को तत्काल तरीके से चालू करने की अनुमति देते हैं जो एक अच्छी तरह से टाइप की गई मोनोमोर्फिक अभिव्यक्ति उत्पन्न करेगी। यह अच्छा है, क्योंकि कभी-कभी आप यह जांचना चाहते हैं कि इस तरह की अभिव्यक्ति का मूल्यांकन करने के लिए आवश्यक उदाहरणों को परिभाषित किए बिना अभिव्यक्ति किस प्रकार की है। जब अभिव्यक्ति का मूल्यांकन किया जाएगा, तो प्रकार चर को एक मोनोमोर्फिक प्रकार प्राप्त करने के लिए तत्काल किया जाना चाहिए, और फिर ghci आवश्यक उदाहरणों को देखता है। यदि उदाहरण गुम हैं, तो इसकी सूचना दी गई है। –

+10

ए 'कोई उदाहरण नहीं ...' संदेश का यह अर्थ यह नहीं है कि अभिव्यक्ति स्वाभाविक रूप से अच्छी तरह से टाइप नहीं की गई है, यह है (वास्तविक प्रकार की त्रुटियों को अलग-अलग संदेश मिलते हैं); लापता उदाहरणों को जोड़कर, आप (लगभग हमेशा) ghci को स्वीकार करने और उसका मूल्यांकन करने के लिए प्राप्त कर सकते हैं। –

16

किसी सूचियां निर्धारित कर सकता है संख्या के रूप में इलाज किया जाना है क्योंकि:,

instance Num a => Num [a] where 
(+) = zipWith (+) 
(*) = zipWith (*) 
(-) = zipWith (-) 
negate = map negate 
abs = map abs 
signum = map signum 
fromInteger x = [fromInteger x] 

तो क्या आप काम करेगा टाइप किया

1++2 == fromInteger 1++fromInteger 2 == [1]++[2] 

के बाद से (यह नहीं कि Num उदाहरण अधिक समझ में आएगा ..)

+11

आप सभी आवेदकों 'टी' ('[]' और '((->) ई) के साथ अधिकतर समझदार 'संख्या' उदाहरण परिभाषित कर सकते हैं '):' उदाहरण (संख्या ए) => न्यूम (टी ए) जहां से इंटेगर = शुद्ध fromInteger; नकारात्मक = लिफ्ट एक नकारात्मक; (+) = लिफ्टए 2 (+); ... ' – melpomene

+2

@melpomene मैंने सोचा कि ठोस उदाहरण यहां सबसे अच्छा होगा। – aleator

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