2015-05-27 17 views
8

गुना समारोह:क्यों फ़ंक्शन (+) मिलान प्रकार (ए -> बी -> बी)?

fold :: b -> (a -> b -> b) -> [a] -> b 
fold z f []  = z 
fold z f (x:xs) = f x (fold z f xs) 

http://www.seas.upenn.edu/~cis194/spring13/lectures/04-higher-order.html

Prelude> :t (+) 
(+) :: Num a => a -> a -> a 

*Main> fold (0) (+) [1,2,3] 
6 

से लिया क्या (+) समारोह के लिए प्रकार a -> a -> a साथ (a -> b -> b) मैच टाइप करता है?

गुना परिभाषा फ़ंक्शन प्रकार (a -> b -> b) स्वीकार करती है इसका मतलब है कि पहले 2 पैरामीटर (a -> b) विभिन्न प्रकार के होने की आवश्यकता है?

+0

सिर्फ इसलिए कि 'ए' और' बी 'अलग-अलग अक्षरों का अर्थ यह नहीं है कि' a/= b'। – AJFarmar

उत्तर

15

नहीं, सब तो इसका मतलब यह है कि a और b अलग हो सकते हैं, लेकिन यह अनिवार्य यह अलग होने के लिए नहीं है। आपके मामले में, यह वही है।

data SomeType a b = Test a b deriving (Show) 

अब ghci में:

+4

'जोड़ी :: ए -> बी -> (ए, बी)' 'डेटा' उदाहरण से भी सरल हो सकता है। – Zeta

3

आप विपरीत दिशा में सोच रहे हैं

एक बहुत सरल उदाहरण बिंदु व्यक्त करने के लिए। आपको यह देखना होगा कि क्या + समान है या मेल खाता a -> b -> b, आप + के प्रकार के एक विशेषज्ञता होने के लिए a -> b -> b की और यह आप करने के लिए है एकजुट प्रकार की जांच करना चाहते नहीं है।

एकीकरण का मतलब है कि आप को देखने के लिए कि क्या + के प्रकार और प्रकार a -> b -> b प्रकार चर का नाम बदलने से बराबर किया जा सकता है चाहता हूँ।

तो + टाइप Num x => x -> x -> x है। चलिए अब कक्षा की बाधा को अनदेखा करते हैं, और देखते हैं कि हम कार्यात्मक प्रकारों से मेल खा सकते हैं या नहीं। प्रकार x -> x -> x और a -> b -> b बन जाते हैं। वास्तव में यह बेहतर है कि अगर हम वास्तव में हैं, तो वे वास्तव में हैं, सहयोगीता का उपयोग किए बिना: x -> (x -> x) और a -> (b -> b)

->प्रकार का निर्माता है। अर्थात। यह एक ऐसा कार्य है जो एक निश्चित प्रकार के प्रकारों को एक अलग प्रकार के लिए मानचित्र करता है। इस मामले में -> कन्स्ट्रक्टर नक्शा दो प्रकार t_1 और t_2 कार्यात्मक प्रकार (->) t_1 t_2 (जिसे आम तौर पर t_1 -> t_2 द्वारा दर्शाया गया है) पर नक्शा करता है।

तो प्रकार x -> (x -> x) वास्तव में (->) x ((->) x x) किस प्रकार निर्माता ->x करने और प्रकार निर्माता ->x और x करने के लिए लागू करने के लिए लागू है। अन्य प्रकार (->) a ((->) b b) है।

एकजुट होने पर आप दो प्रकार के लिए बाहरी प्रकार के निर्माता (-> इस मामले में दोनों के लिए) मानते हैं। यदि यह मेल नहीं खाता है, तो आप एकजुट नहीं कर सकते हैं। अन्यथा आपको कन्स्ट्रक्टर के तर्कों को एकजुट करना होगा।

इसलिए हमें को a के साथ एकीकृत करना होगा। वे दोनों प्रकार के चर हैं, इसलिए हम का नाम बदल सकते हैं। मान लीजिए कि हम a का नाम x के साथ बदलते हैं। तो अब हम प्रकारों के नामकरण को लागू करते हैं, प्राप्त करते हैं: (->) x ((->) x x) और (->) x ((->) b b) और आप देखते हैं कि x और x अब मिलान करें।

चलो दूसरे तर्क पर विचार करें। यह एक प्रकार परिवर्तनीय नहीं है इसलिए हमें प्रकार के कन्स्ट्रक्टर से मिलान करना होगा, और यह दोनों के लिए -> है। तो हम तर्कों पर पुनरावर्ती प्रक्रिया करते हैं।

हम x और b से मेल खाना चाहते हैं। वे दोनों प्रकार के चर हैं, इसलिए हम उनमें से एक का नाम बदल सकते हैं। मान लें कि हम xb का नाम बदलते हैं। हम इस प्रतिस्थापन को प्रकारों पर लागू करते हैं, प्राप्त करते हैं: (->) b ((->) b b) और (->) b ((->) b b)। अब सब कुछ मेल खाता है। इसलिए दो प्रकार एकजुट होते हैं।

वर्ग बाधा के बारे में, जब हम xb साथ हम बाधा को प्रतिस्थापन लागू किया नाम बदलने भी तो Num xNum b बन गया है और दो अंतिम प्रकार दोनों Num b => b -> b -> b हैं।

मुझे आशा है कि इससे आपको कुछ बेहतर समझ मिलेगी कि प्रकार कैसे काम करते हैं और प्रकारों की जांच कैसे की जाती है।


साइड नोट: टाइप अनुमान लगाने के दौरान यह हैकेल करता है। यह पहले एक अज्ञात फ़ंक्शन को एक ताजा प्रकार परिवर्तनीय t असाइन करता है। फिर यह अभिव्यक्ति के प्रकार को प्राप्त करने के लिए एकीकरण का उपयोग करता है जो इसे परिभाषित करता है और जांचता है कि t के साथ किस प्रकार से जुड़े थे, और यह फ़ंक्शन का प्रकार है।

+0

मुझे लगता है कि यह प्रकार के रचनाकारों के साथ थोड़ा यांत्रिक हो रहा है। एक अवधारणात्मक उदाहरण (यानी जो के साथ एकीकृत हो जाता है) एकीकरण प्रक्रिया के संचालन के उदाहरण से पहले उपयोगी होगा। – Cubic

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