2012-05-06 19 views
5

मैं हास्केल के लिए अपेक्षाकृत नया हूं, अगर मेरा प्रश्न बेवकूफ लगता है। मैं यह समझने की कोशिश कर रहा हूं कि कार्य रचना कैसे काम करती है और मुझे एक समस्या आई है कि मैं सोच रहा था कि कोई मेरी मदद कर सकता है। मैं निम्नलिखित दो स्थितियों में एक समारोह संरचना में मानचित्र का उपयोग कर रहा:हास्केल: फ़ंक्शन संरचना में मानचित्र का उपयोग

  • map (*2) . filter even [1,2,3,4]
  • map (*2) . zipWith max [1,2] [4,5]

हालांकि दोनों फिल्टर और zipWith कार्यों एक सूची प्रदान, केवल पहली रचना है, जबकि दूसरा काम करता है संरचना नीचे त्रुटि को फेंकता है:

"Couldn't match expected type '[Int] -> [Int]' with actual type '[c0]' 

किसी भी सुझाव की सराहना की जाएगी।

+1

[इस प्रश्न] के उत्तर दें [http://stackoverflow.com/questions/2834626/haskell-dot-operator) मदद? (विशेष रूप से [यह एक] (http://stackoverflow.com/a/2834661/1256624)) – huon

+1

पहला व्यक्ति वास्तव में आउटपुट का उत्पादन करता है 'वास्तविक प्रकार के साथ अपेक्षित प्रकार a0 -> [b0]' से मेल नहीं खाता [a1] ' –

उत्तर

5

zipWith max [1,2] [4,5] का परिणाम एक सूची है, न कि एक समारोह। (।) ऑपरेटर को फ़ंक्शन को इसके दाएं ऑपरेंड के रूप में आवश्यक है। इसलिए आपकी दूसरी पंक्ति में त्रुटि। शायद तुम क्या चाहते

map (*2) (zipWith max [1,2] [4,5]) 

आपका पहला उदाहरण WinHugs पर संकलन नहीं करता है (हग्स मोड) है; यह एक ही त्रुटि है। निम्नलिखित

(map (*2) . filter even) [1,2,3,4] 

क्योंकि यह दो कार्यों को लिखता है और परिणामी फ़ंक्शन को तर्क में लागू करता है।

16

(.) के प्रकार को याद करें।

(.) :: (b -> c) -> (a -> b) -> a -> c 

यह तीन तथ्य होते हैं: दो कार्य करता है और एक प्रारंभिक मूल्य, और बना दो कार्यों का परिणाम देता है।

अब, अपने तर्कों के लिए एक फ़ंक्शन का उपयोग (.) ऑपरेटर से अधिक कठिन है। तो अपने अभिव्यक्ति:

map (*2) . filter even [1,2,3,4] 

पार्स किया गया है के रूप में:

(.) (map (*2)) (filter even [1,2,3,4]) 
अब

, पहला तर्क, map (*2) ठीक है। इसमें (b -> c) टाइप किया गया है, जहां b और cNum a => [a] है।

Prelude> :t filter even [1,2,3,4] 
filter even [1,2,3,4] :: Integral a => [a] 

और इतने प्रकार चेकर शिकायत करेगा कि आप एक तर्क के रूप में एक [a] गुजर रहे हैं जब (.) समारोह एक समारोह की जरूरत है: हालांकि, दूसरा तर्क एक सूची है।

और वह हम देखते है:

Couldn't match expected type `a0 -> [b0]' with actual type `[a1]' 
In the return type of a call of `filter' 
In the second argument of `(.)', namely `filter even [1, 2, 3, 4]' 
In the expression: map (* 2) . filter even [1, 2, 3, 4] 

तो ... parenthesization!

map (*2) . filter even $ [1,2,3,4] 

या स्पष्ट कोष्ठक का उपयोग करें, दो कार्यों

map (*2) (filter even [1,2,3,4]) 

या यहाँ तक कि की संरचना को हटाने:

(map (*2) . filter even) [1,2,3,4] 
+0

धन्यवाद डॉन। यह वास्तव में उपयोगी था – wajeeh

+1

यदि यह सहायक था तो आपको डॉन के जवाब को स्वीकार करना चाहिए। – augustss

+1

मुझे पता है कि ओपी ने विशेष रूप से फ़ंक्शन संरचना के बारे में पूछा है, लेकिन यह उदाहरण वास्तव में '$', _i.e._, 'map (* 2) $ फ़िल्टर तक सीधे सर्वोत्तम है [1,2,3,4]' । – apc

4

या तो एक कोष्ठक जोड़ने के लिए $ ऑपरेटर का उपयोग निम्नलिखित फॉर्म मान्य हैं:

map (* 2) $ filter even [1, 2, 3, 4] 
(map (* 2) . filter even) [1, 2, 3, 4] 
map (* 2) $ zipWith max [1, 2] [4, 5] 
(\xs -> map (* 2) . zipWith max xs) [1, 2] [4, 5] 

नहीं बल्कि निम्नलिखित:

map (* 2) . filter even [1, 2, 3, 4] 
map (* 2) . zipWith max [1, 2] [4, 5] 
(map (* 2) . zipWith max) [1, 2] [4, 5] 

ताकि क्यों है? ठीक है, उदाहरण के

map (* 2) . zipWith max [1, 2] [4, 5] 

के लिए ले यह रूप में

(map (* 2)) . (((zipWith max) [1, 2]) [4, 5]) 

(map (* 2)) ही [Int] -> [Int] (Int के लिए दोषी मानते हुए) टाइप किया है, (((zipWith max) [1, 2]) [4, 5]) टाइप [Int] है और (.) इस गैर में (b -> c) -> (a -> b) -> a -> c या ([Int] -> [Int]) -> ([Int] -> [Int]) -> [Int] -> [Int] टाइप है polymorphic मामला, तो यह बीमार टाइप है।

(map (* 2)) $ (((zipWith max) [1, 2]) [4, 5]) 

अच्छी तरह से आपके द्वारा लिखा गया है: दूसरी ओर ($) पर टाइप (a -> b) -> a -> b, या इस गैर बहुरूपी मामले में ([Int] -> [Int]) -> [Int] -> [Int], तो यह है।

2

(.) की कम पूर्वता के कारण, हास्केल पार्स

map (*2) . (filter even [1,2,3,4]) 

यानी filter even [1,2,3,4] (एक सूची) का परिणाम है, जो कोई मतलब नहीं है के साथ रचना

map (*2) . filter even [1,2,3,4] 

रूप

map (*2) (एक समारोह) , और एक प्रकार की त्रुटि है।

आप इस का उपयोग करते हुए @ थिओडोर के सुझावों को ठीक कर सकते हैं, या ($) का उपयोग करके:

map (*2) . filter even $ [1,2,3,4] 
2

आप नक्शे के प्रकार यह है जांच: (a -> b) -> [a] -> [b]

इसलिए, यह ख में एक के एक समारोह लेता है और फिर एक की एक सूची और बी की एक सूची देता है। सही?

अब, आप पहले से ही पैरामीटर (*2) पास करके बी में एक फ़ंक्शन प्रदान करते हैं। इसलिए, आपका आंशिक रूप से लागू मानचित्र फ़ंक्शन समाप्त हो रहा है: [Integer] -> [Integer] जिसका अर्थ है कि आपको पूर्णांक की एक सूची प्राप्त होगी और पूर्णांक की एक सूची वापस कर दी जाएगी।

इस बिंदु तक, आप (।) एक फ़ंक्शन लिख सकते हैं जिसमें एक ही हस्ताक्षर है। यदि आप filter even के प्रकार की जांच करते हैं तो आप देखेंगे कि यह है: [Integer] -> [Integer], यहां रचना के लिए ऐसे वैध उम्मीदवार के रूप में।

यह रचना तो, समारोह के अंतिम हस्ताक्षर, यदि आप के प्रकार की जांच में परिवर्तन नहीं करता: map (*2) . filter even यह है [Integer] -> [Integer]

यह map (*2) . zipWith max [1,2] [4,5] के मामले नहीं होगी, क्योंकि zipWith max ही नहीं है map (*2) द्वारा अपेक्षित एक के रूप में हस्ताक्षर।

+0

धन्यवाद। अब सब समझ आ रहा है – wajeeh