2012-10-26 15 views
7

के एक उदाहरण के रूप में कार्य मुझे यह समझने में कठिनाई हो रही है कि एक समारोह एक मोनड कैसे हो सकता है।मोनाड

instance Monad ((->) r) where 
    return x = \_ -> x 
    h >>= f = \w -> f (h w) w 

यहां तक ​​कि क्या मिरान Lipovača says के बारे में यह मुझे उलझन में आता है:

समारोह (->) rControl.Monad.Instances में एक घोषणा के अनुसार एक इकाई है,

>>= के लिए कार्यान्वयन एक सा लगता है, लेकिन गुप्त यह वास्तव में नहीं है। जब हम किसी फ़ंक्शन में एक monadic मान फ़ीड करने के लिए >>= का उपयोग करते हैं, तो परिणाम हमेशा एक monadic value है। तो इस मामले में, जब हम फ़ंक्शन को किसी अन्य फ़ंक्शन पर फ़ीड करते हैं, तो परिणाम भी एक फ़ंक्शन होता है। यह क्यों परिणाम लैम्ब्डा के रूप में शुरू होता है। >>= के सभी कार्यान्वयन अब तक किसी भी तरह से monadic मूल्य से परिणाम अलग कर दिया और फिर उस परिणाम को फ़ंक्शन f लागू किया। वही बात यहां होती है। किसी फ़ंक्शन से परिणाम प्राप्त करने के लिए, हमें इसे पर लागू करना होगा, यही कारण है कि हम (h w) पर फ़ंक्शन से परिणाम प्राप्त करने के लिए यहां हैं और फिर हम उस पर लागू होते हैं। एफ एक monadic मूल्य देता है, जो हमारे मामले में एक समारोह है, इसलिए हम इसे भी लागू करने के लिए लागू करते हैं। -> (एक -> एमबी) -> एमबी

तो मैं ले कि h के रूप में लिखा गया (>> =) :: मा:

के प्रकार के हस्ताक्षर (>> =) यह है m a और f(a -> m b) के रूप में। यदि कोई फ़ंक्शन m a है, तो क्या यह a प्रकार मान देता है? या यह a प्रकार लेते हुए कुछ और लौटाता है?

h के गैर इकाई मूल्य f को खिलाया जाता है, तो हम पाते हैं: च (ज डब्ल्यू) ठीक लग रहा है। चूंकि f एक फ़ंक्शन है और उसने अपना एकमात्र तर्क लिया है, यह पहले से ही एक मान है, नहीं? चूंकि यह एक monadic समारोह है मूल्य भी एक monadic मूल्य है। फिर उसे एक और मूल्य w क्यों चाहिए? wf something को खिला नहीं रहा है, यह गैर-मोनैडिक बनाते हैं, यानी, यह कोई फ़ंक्शन नहीं है, नहीं? मैं यह भी समझ नहीं पा रहा हूं कि क्यों f something और h एक ही तर्क w लेते हैं और विभिन्न मान प्रकार (m a और m b) लौटाते हैं।

उत्तर

10

सबसे पहले, यहाँ (>>=) के प्रकार है कुछ अनावश्यक कोष्ठक:

(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b 

जो बिंदु पर यह देखने के लिए क्या हो रहा है बहुत आसान होना चाहिए: (प्रकार r का) तीसरा तर्क पहला तर्क को दिया जाता है प्रकार a के बारे में कुछ पाने के लिए है, तो दोनों परिणाम और तीसरा तर्क है कि b के अंतिम परिणाम प्राप्त करने के लिए दूसरे तर्क को दिया जाता है।

तो, ((->) r) एक Monad के रूप में है कि इकाई में हर मूल्य के लिए एक अतिरिक्त समारोह तर्क का प्रतिनिधित्व करता है, और जब monadic मूल्यों जोड़ दिया जाता है एक "अतिरिक्त" तर्क दोहराया और प्रत्येक इनपुट मूल्य को दिया जाता है। अनिवार्य रूप से, यह monadic मूल्यों के लिए एक "केवल पढ़ने के लिए वैश्विक पर्यावरण" बनाता है। यह व्याख्या स्पष्ट रूप से Reader मोनैड के रूप में प्रदान की जाती है, जो ((->) r) के आसपास सिर्फ एक रैपर है।

+0

धन्यवाद। सब कुछ स्पष्ट है! – amemus

5

यह शायद को देखकर इस इकाई को समझने के लिए आसान है क्या join करता है, एक इकाई समतुल्य रूप fmap और join बजाय >>= का उपयोग कर परिभाषित किया जा सकता के बाद से।

join का सामान्य रूप प्रकार Monad m => m (m b) -> m b है, इसलिए यह एक "दो परत" monadic मान लेता है और इसे एक परत पर crunches।

समारोह इकाई, m ~ (a ->) साथ

, तो join प्रकार (a -> a -> b) -> (a -> b) तो यह दो तर्क के एक समारोह लेता है और एक समारोह है कि केवल एक लेता देता है।

join :: (a -> a -> b) -> (a -> b) 
join f = \x -> f x x 

आप देख सकते हैं, यह सिर्फ तर्क डुप्लिकेट।

इसी प्रकार, fmap फ़ंक्शंस पर फ़ंक्शन संरचना है, और returnconst है।

मुझे लगता है कि >>= की भावना बनाने की कोशिश करने से इस तरह समझना बहुत आसान है।

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b 
अब

, m विशेष ((->) r) के साथ:

(>>=) :: ((->) r) a -> (a -> ((->) r) b) -> ((->) r) b 

सभी कार्य तीर इन्फ़िक्स साथ फिर से लिखा:

(>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b) 

निकाला जा रहा है

+0

हालांकि यह अवधारणा को अवधारणा को समझने के लिए उपयोगी है, फिर भी आपको उस मोनाड के लिए 'डू' नोटेशन में प्रत्येक पंक्ति को क्या करना है, उसे समझने के लिए आपको अभी भी '>> =' के व्यवहार को समझना होगा। –

+0

@ डैनबर्टन: इस मामले में मुझे लगता है कि 'आवेदक' उदाहरण समझाने और समझने के लिए सबसे आसान है क्योंकि "पर्यावरण" हमेशा पहला तर्क होता है, और 'मोनाड' उदाहरण पैरामीटर ऑर्डर के बराबर होता है। –

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