2010-06-29 25 views
28

मैं रियल वर्ल्ड हास्केल के I/O अध्याय पर हूं। किसी अन्य 7 अध्यायों के लिए पुस्तक में मोनाड्स पर चर्चा नहीं की गई है। जो कहना है, I/O की मेरी समझ सबसे अच्छी, अपूर्ण है।मानचित्र बनाम मानचित्र एम व्यवहार

अभी मैं mapM फ़ंक्शन को समझने की कोशिश कर रहा हूं। जैसा कि मैं इसे समझता हूं, फ़ंक्शन सूची में प्रत्येक तत्व "निष्पादित" करता है जो "क्रिया" (आईओ मोनैड) होना चाहिए।

क्या समझ में नहीं आता this example है। मैपएम एक ही तर्क के लिए मानचित्र से अलग परिणाम क्यों देता है?

Prelude> map (\x -> [x]) [0, 1, 2] 
[[0],[1],[2]] 
Prelude> mapM (\x -> [x]) [0, 1, 2] 
[[0,1,2]]
+0

भी मजेदार: 'लंबाई (mapM (\\ _-> ए) बी) == लंबाई^^ लंबाई बी'। मुझे लगता है। – muhmuhten

उत्तर

18

मैं यह समझ के रूप में, समारोह सूची है जो एक "कार्रवाई" होना चाहिए में प्रत्येक तत्व (आईओ इकाई) "निष्पादित करता है"।

कि आईओ के लिए सच है, लेकिन अपने कोड उदाहरण में आप आईओ इकाई का उपयोग नहीं करते, तो आप सूची इकाई का उपयोग करें (समारोह आप mapM को देने के एक सूची ([x] रिटर्न), नहीं एक आईओ)।

mapM को mapM f as = sequence (map f as) के रूप में परिभाषित किया गया है। यदि एफ आईओ लौटाता है तो इसका मतलब है कि सूची में प्रत्येक तत्व के लिए यह तत्व को एफ लागू करके आईओ बनाता है। इसके बाद आईओएस की सूची बदल जाती है जो मैप अनुक्रम का उपयोग करते हुए एक सूची "आईओ" में लौटाता है (इसलिए जब आप आईओ निष्पादित करते हैं, तो आपको गैर-आईओ मान वाली एक सूची वापस मिलती है)।

सूचियों के लिए इसका अर्थ है कि यह as के प्रत्येक तत्व में f लागू करके सूचियों की एक सूची बनाता है। यह सूचियों की सूची बनाने के लिए sequence का उपयोग करता है जिसमें सूचियों की सूचियों में प्रत्येक सूची का एक तत्व लेने के सभी संभावित तरीके शामिल हैं (उदा। sequence [[1,2],[3,4]][[1,3],[1,4],[2,3],[2,4]] लौटाता है)।

+3

इस पर विस्तार करने के लिए। मैपएम की परिभाषा के प्रकाश में, अनुक्रम के प्रकार को लागू करें: अनुक्रम :: (मोनाड एम) => [एम ए] -> एम [ए] दिए गए उदाहरण में। मैपएम (\ x -> [x]) [0, 1, 2] = अनुक्रम (मानचित्र (\ x -> [x]) [0, 1, 2]) = अनुक्रम [[0], [1] , [2]] = [[0,1,2]] –

+1

मैथ्यू एस: आपकी टिप्पणी बहुत उपयोगी थी, धन्यवाद। – titaniumdecoy

10

शायद यह स्पष्ट करने लायक है कि ये दो स्निपेट 'समान' नहीं हैं और आपको संबंधित परिणामों की अपेक्षा नहीं करनी चाहिए। विशेष रूप से, एक 'monadic' की

मानचित्र संस्करण (\ एक्स -> [x]) [0, 1, 2]

mapM (है \ एक्स - > वापसी [x]) [0, 1, 2]

अतिरिक्त return पर ध्यान दें।

सामान्य रूप से, return (map f x)mapM (return . f) x जैसा ही है।

ऐसा इसलिए है क्योंकि सूची मोनड, x >>= ff को x पर लागू करने के परिणाम 'flattens' के परिणामस्वरूप है। जब आपने return को छोड़ दिया तो \x -> [x] को लागू करने के नतीजे परिणाम में चपटे हो रहे थे। अतिरिक्त return अतिरिक्त फ़्लैटनिंग को रद्द कर देता है।

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