2013-05-06 5 views
6

यह भावना एकाधिक flatMap (या >>=/हास्केल में bind) एक इकाई में तरीकों को परिभाषित करने को करता है? बहुत कुछ monads मैं वास्तव में (Option, Try, Either अनुमानों) का उपयोग केवल एक flatMap विधि परिभाषित करते हैं।एक मोनैड के लिए एकाधिक फ्लैटमैप विधियां?

उदाहरण के लिए, पर flatMap विधि को परिभाषित करने के लिए यह समझ में आता है जो Try का निर्माण करने वाला एक कार्य करेगा? तो Option[Try[User]] उदाहरण के लिए Option[User] के रूप में फ़्लैट किया जाएगा? (अपवाद को खोने पर विचार करना कोई समस्या नहीं है ...)

या एक मोनड को एक flatMap विधि को परिभाषित करना चाहिए, जो एक ही प्रकार का मोनड उत्पन्न करता है? मुझे लगता है कि इस मामले में Either अनुमान मोनैड नहीं होंगे? क्या वो?

+0

@ ओम-nom-nom और: यह पता चला है के रूप में, इस तरह के एक निर्माण (सभी monadic क्षमताओं को खोने के अलावा) नहीं वाकई दिलचस्प है, क्योंकि यह बाहरी कंटेनर के लिए भीतरी से एक रूपांतरण प्रदान करने के लिए पर्याप्त है सूची तब एक मोनाड है? जिस तरह से मैं यह नहीं ढूंढ सकता कि यह 'सूची [विकल्प [_]]' के लिए कैसे काम करता है क्योंकि विकल्प एक GenTraversableOnce –

+0

'या तो' इसके प्रकार के चर दोनों पर एक मोनड नहीं है। क्या आप यही पूछ रहे हैं? –

उत्तर

5

मैंने एक बार गंभीरता से इस बारे में सोचा है।

joinWith :: (Functor m, Monad m) => (n a -> m a) -> m (n a) -> m a 
joinWith i = join . (fmap i) 

bindWith :: (Functor m, Monad m) => (n a -> m a) -> m a -> (a -> n a) -> m a 
bindWith i x f = joinWith i $ fmap f x 

*Main> let maybeToList = (\x -> case x of Nothing -> []; (Just y) -> [y]) 
*Main> bindWith maybeToList [1..9] (\x -> if even x then Just x else Nothing) 
[2,4,6,8] 
+2

यह एक अच्छा जवाब है। मेरी समझ यह है कि यह सिद्धांत के साथ भी अच्छी तरह से फिट बैठता है: 'n a>> m a' फ़ंक्शन 'n' और' m' functors के बीच एक प्राकृतिक परिवर्तन का प्रतिनिधित्व करता है। मान लीजिए कि यह मोनैड ऑपरेशंस का सम्मान करता है, यह 'एन' और' एम 'के बीच एक मोनोड होमोमोर्फिज्म का भी प्रतिनिधित्व करता है। –

+0

क्षमा करें क्योंकि आपका जवाब चतुर है, यह उस प्रश्न का उत्तर नहीं देता है जो 'एकल मोनैड के लिए एकाधिक फ्लैटमैप विधियां' है। निस्संदेह हम दो अलग-अलग मोनैड को एक चुनिंदा तरीके से संलयन करने का एक तरीका ढूंढ सकते हैं, लेकिन इस प्रकार के परिवर्तन से यह एक मोनड भी होता है? और मैं नहीं देखता कि आपका जवाब उसे समझने में कैसे मदद कर सकता है कि यह एक मोनड क्यों नहीं है। – zurgl

+0

यह उत्तर लगभग सही है, इमो। एक और बात जो मैं इंगित करूंगा वह यह है कि यदि आपके पास 'एम -> (ए -> एनबी) -> एनबी' है जो मोनिशिश कानूनों का पालन करता है, तो आप इसे एक मोनड मॉर्फिज्म' एम -> एनबी' बनाकर ' दूसरे तर्क के रूप में वापसी '। सिमिलरली, 'एम ए -> (ए -> एन बी) -> एम बी' जैसे एक समारोह को मोनाड मॉर्फिज्म 'एन ए -> एम बी' में बदले में और अधिक काम के साथ बदल दिया जा सकता है। –

1

यह "समझ में आता है" का अर्थ है।

क्या आपका मतलब यह इकाई कानूनों के अनुरूप है, तो यह बिल्कुल मेरे लिए स्पष्ट सवाल पूरी तरह से समझ में आता है है। मुझे बताने के लिए एक ठोस प्रस्ताव देखना होगा। यदि आप ऐसा सोचते हैं जो आपको लगता है कि आप सुझाव देते हैं, तो संभवतः आप कम से कम कुछ कोने मामलों में संरचना का उल्लंघन करेंगे।

क्या आपका मतलब यह उपयोगी, सुनिश्चित करें, आप हमेशा ऐसे मामलों में जहां इस तरह की चीजों उपयोगी होते हैं पा सकते हैं है। समस्या यह है कि यदि आप मोनैड कानूनों का उल्लंघन करना शुरू करते हैं, तो आपने अनचाहे कार्यात्मक (श्रेणी सिद्धांत) तर्ककर्ता के लिए अपने कोड में जाल छोड़े हैं। बेहतर, चीजें हैं जो monads तरह तरह का लग वास्तव में monads (और सिर्फ एक बार में एक ही हो सकता है बनाने के लिए --but आप सही है कि LeftProjection लिखा और RightProjection के रूप में कर रहे हैं नहीं कर रहे हैं, हालांकि आप एक स्पष्ट तरीका एक ला Either स्विच करने के लिए प्रदान कर सकते हैं, सख्ती बोलना, monads)। या वास्तव में स्पष्ट दस्तावेज़ लिखते हुए बताते हैं कि ऐसा नहीं लगता है। अन्यथा कोई कानून कानून धारण करने के साथ मिलकर जायेगा, और * विभाजन *।

1

यह एक विशिष्ट डेटा प्रकार के लिए, मतलब नहीं है, जहाँ तक मुझे पता है, आप केवल bind के लिए एक परिभाषा हो सकती है।

हास्केल में एक इकाई के निम्न प्रकार के वर्ग है,

instance Monad m where 
    return :: a -> m a 
    bind :: m a -> (a -> m b) -> m b 

Concretely सूची इकाई हमारे पास है, के लिए

instance Monad [] where 
    return :: a -> [] a 
    (>>=) :: [] a -> (a -> [] b) -> [] b 

अब के रूप में एक monadic समारोह पर विचार करें।

actOnList :: a -> [] b 
.... 

मामला उपयोग वर्णन करने के लिए,

$ [1,2,3] >>= actOnList 

समारोह actOnList हम देखते हैं कि एक सूची एक और प्रकार (यहाँ []) द्वारा एक बहुरूपी प्रकार बाधा है पर। फिर जब हम सूची मोनैड के लिए बाइंड ऑपरेटर के बारे में बात करते हैं तो हम [] a -> (a -> [] b) -> [] b द्वारा परिभाषित बाइंड ऑपरेटर के बारे में बात करते हैं।

आप क्या हासिल करना चाहते हैं एक bind ऑपरेटर [] Maybe a -> (a -> [] b) -> [] b तरह परिभाषित, पहले एक के इस मत के विशेषज्ञ संस्करण लेकिन एक और समारोह और यह हस्ताक्षर मैं सच में संदेह है कि यह के रूप में इकाई के किसी भी प्रकार की bind ऑपरेटर हो सकता है टाइप के बारे में है आप जो भी खा चुके हैं उसे वापस न करें।आप निश्चित रूप से फ़ंक्शन का उपयोग करके एक मोनड से दूसरे में जाते हैं लेकिन यह फ़ंक्शन निश्चित रूप से सूची के bind ऑपरेटर का एक और संस्करण नहीं है।

यही कारण है कि मैंने कहा है, यह एक विशिष्ट डेटा प्रकार के लिए समझ में नहीं आता है, जहां तक ​​मुझे पता है, आप केवल bind के लिए एक परिभाषा प्राप्त कर सकते हैं।

1

flatMap या (>>=) आपके Option[Try[ ]] उदाहरण के लिए टाइप चेक नहीं करता है। छद्म हास्केल अंकन

type OptionTry x = Option (Try x) 

instance Monad OptionTry where 
    (>>=) :: OptionTry a -> (a -> OptionTry b) -> OptionTry b 
    ... 

में हम bind/flatMap जरूरत इनपुट मूल्य के रूप में एक ही संदर्भ में लिपटे एक मूल्य के वापस जाने के लिए।

हम समकक्ष return/join एक मोनाड के कार्यान्वयन को देख कर इसे देख सकते हैं। OptionTry के लिए, join विशेष प्रकार

instance Monad OptionTry where 
    join :: OptionTry (OptionTry a) -> OptionTry a 
    ... 

यह देखने में का एक सा के साथ स्पष्ट किया जाना चाहिए कि "फ्लैट" flatMap का हिस्सा join है (या concat सूचियों जहां नाम से निकला है के लिए) है।

अब, एक डेटाटाइप के लिए कई अलग-अलग bind एस के लिए संभव है। गणितीय रूप से, एक मोनाड वास्तव में डेटा प्रकार (या, वास्तव में, मोनैड के मानों का सेट होता है) के साथ bind और return संचालन के साथ। विभिन्न परिचालन अलग-अलग (गणितीय) मोनाड्स का कारण बनता है।

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