2013-02-02 51 views
5

तो, चलिए सीधे बिंदु पर आते हैं।मानचित्र। फ़ोल्डर फ़ंक्शन संरचना - हास्केल

:t (map.foldr) 
(map.foldr) :: (a1 -> a -> a) -> [a] -> [[a1] -> a] 

[[a1] -> a] क्या है? मैं वास्तव में इस रचना को समझने के लिए कोशिश कर रहा हूँ, इसलिए मैं यह कर रहा था:

-- map.foldr 

    map.foldr :: (a1 -> a -> a) -> [a] -> [[a1] -> a] 

    map :: (a1 -> b1) -> [a1] -> [b1] 
    (.) :: (y -> w) -> (x -> y) -> x -> w 
    foldr :: (a -> b -> b) -> b -> [a] -> b 

    y = (a1 -> b1)  w = ([a1] -> [b1]) 
    x = (a -> b -> b) y = (b -> [a] -> b) 

    y = (a1 -> b1) 
    y = (b -> [a] -> b) 
_________________________ 

क्या इस बात में क्या होता है? धन्यवाद!

+1

'फ़ोल्डर' प्रकार गलत है,' (ए -> बी -> बी) -> बी -> [ए] -> बी' होना चाहिए। –

उत्तर

14

इस सवाल यह क्या याद करने के लिए अच्छा है जवाब देने के लिए foldr और map करो।

1 : 2 : 3 : [] 

कार्रवाई:

अधिक दो की जटिल foldr, वास्तव में conses (:) और एक टर्मिनल खाली सूची की एक श्रृंखला है

--    list to be folded 
--        v 
foldr :: (a -> b -> b) -> b -> [a] -> b 
--   ^  ^
--folding function  terminal value 

टाइप सूची तह किया जा करने के लिए है जो है foldr: और [] फ़ोल्डिंग फ़ंक्शन और टर्मिनल मान के साथ रचनाकारों को प्रतिस्थापित करना है:

foldr (+) 0 (1 : 2 : 3 : []) == 1 + 2 + 3 + 0 

map समारोह सरल है।

map :: (a -> b) -> [a] -> [b] 
--  ^  ^
-- function   list 

हालांकि, अगर आप भी एक समारोह लेने, और करने के लिए इसे उठाने के रूप में यह के बारे में सोच सकते हैं: यह के बारे में सोच का एक तरीका यह सूची के हर तर्क करने के लिए एक समारोह और एक सूची समारोह लेने, और आवेदन के रूप में है

map :: (a -> b) -> ([a] -> [b]) 
--  ^   ^
-- function    function on lists 

क्या यह इन दोनों कार्यों की रचना करने, map . foldr मतलब है: एक समारोह है कि बजाय सूचियों पर काम करता है हो सकता है?ध्यान दें कि यह सिर्फ काम करता है एक के बाद एक आवेदन कर रहा है - विशेष रूप से,

(map . foldr) f == map (foldr f) 

के बाद से आप लागू foldr पहले, आप एक समारोह f :: a -> b -> b पर लागू किया जाना चाहिए, और यदि आप किसी अन्य समारोह वापस पाने:

foldr f :: b -> [a] -> b 
--  ^ ^
--terminal val list to be folded 

map (foldr f) :: [b] -> [[a] -> b] 
--    ^  ^
--list of terminal vals  functions that fold lists 

इस प्रकार का अजीब लग रहा है, बू:

अब आप map, जो समारोह सूचियों पर कार्य करने के लिए लिफ्टों लागू यह मान्य है। अब एक टर्मिनल मान की बजाय, आप इसे टर्मिनल मानों की एक सूची देते हैं, और आपको फोल्डिंग फ़ंक्शंस की एक सूची वापस मिलती है - एक आपके द्वारा प्रदान किए गए प्रत्येक टर्मिनल मान के लिए।


यह स्पष्ट है कि हम एक विशेष कार्य, (+), है जो देख सकता टाइप

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

अगर हम समीकरण में ऊपर स्थानापन्न कि, हम

(map . foldr) (+) :: Num a => [a] -> [[a] -> a] 
--       ^  ^
--   list of terminal vals   functions that fold lists 

तो मिल बनाने के लिए अब हम इसे [0, 1, 2] सूची में लागू करते हैं, हमें तीन कार्यों की एक सूची मिलती है:

(map . foldr) (+) [0,1,2] :: Num a => [[a] -> a] 

हम किसी विशेष तर्क में सूची में से प्रत्येक कार्य को लागू करने के लिए map ($x) idiom का उपयोग कर सकते हैं। इसे संख्याओं की एक सूची होना है, और मैं [3,4,5] चुनूंगा। ध्यान से देखें:

> map ($[3,4,5]) ((map.foldr) (+) [0,1,2]) 
[12, 13, 14] 

सूची [3,4,5] तह समारोह के रूप में (+) का उपयोग कर तीन बार मुड़ा हुआ था, और एक अलग टर्मिनल से प्रत्येक का मान समय:

3 + 4 + 5 + 0 == 12 
3 + 4 + 5 + 1 == 13 
3 + 4 + 5 + 2 == 14 

जब टर्मिनल मूल्य 0 है, हम बस मिल मानों का योग: 3 + 4 + 5 == 12। जब टर्मिनल मान 1 होता है तो हमें मानों की संख्या (13) से अधिक मिलता है और जब टर्मिनल मान 2 होता है तो हमें मानों के योग (14) से दो और मिलता है।

+0

मुझे "मानचित्र ($ x)" मुहावरे के बारे में अधिक जानकारी कहां मिल सकती है? मैं यह समझ नहीं सकता। ओह, और उत्तर के लिए धन्यवाद, वास्तव में सहायक :) – dehq

+1

ऑपरेटर '$' को 'f $ x = f x' द्वारा परिभाषित किया गया है, यानी यह अपने दायीं तरफ के दायीं ओर फ़ंक्शन पर लागू होता है। यह सख्ती से अनावश्यक है, लेकिन यह दो तरीकों से सहायक है: 1. '$' ऑपरेटर की सबसे कम प्राथमिकता है और सहयोगी सही है (फ़ंक्शन एप्लिकेशन के विपरीत जिसमें उच्च प्राथमिकता और सहयोगी शेष हैं) ताकि आप इसके बजाय 'fa $ gb $ hc' लिख सकें 'एफए (जीबी (एचसी))', और 2. आप इसे एक सेक्शन में उपयोग कर सकते हैं, ताकि आप '\ a -> fa' के बजाय' ($ f) 'लिख सकें। कोड 'मानचित्र ($ x) 'का अर्थ है' मानचित्र (\ a -> x a)' के समान। –

1
map.foldr :: (a1 -> a -> a) -> [a] -> [[a1] -> a] 

map :: (a1 -> b1) -> [a1] -> [b1] 
(.) :: (y -> w) -> (x -> y) -> x -> w 
foldr :: (a -> b -> b) -> b -> [a] -> b 

-- if you substitute: x = (a -> b -> b) y = (b -> [a] -> b) 
-- then you get for map :: (b -> ([a] -> b)) -> [b] -> [[a] -> b] 
-- so if composition operator applied: 
map . foldr :: (a -> b -> b) -> [b] -> [[a] -> b] 
2

जारी रखने के लिए जहां आपने छोड़ा था, y की दो परिभाषाएं बराबर होना चाहिए:

a1 = b 
b1 = [a] -> b 

समारोह रचना दो की आपूर्ति की गई है:

y = (a1 -> b1) = (b -> [a] -> b) 
       = (b -> ([a] -> b)) 

तो हम निष्कर्ष निकाल सकते हैं कि फ़ंक्शन तर्क, इसलिए परिणामस्वरूप प्रकार केवल:

x -> w 

लेकिन हम जानते हैं:

x = a -> b -> b 
w = [a1] -> [b1] = [b] -> [[a] -> b] 

तो, परिणाम प्रकार है:

(x -> w) = ((a -> b -> b) -> ([b] -> [[a] -> b])) 
     = (a -> b -> b) -> [b] -> [[a] -> b] 

जो करने के लिए अनुकूल है:

(a1 -> a -> a) -> [a] -> [[a1] -> a]