2013-11-24 6 views
6

मैं देख सकता हूं कि आप इस ऑपरेशन के लिए गणना के आसपास एक कंटेनर बनाने के लिए आईओ के लिए मोनाड हास्केल का उपयोग कैसे करेंगे। यह समझ में आता है कि आप मोनाड्स को 'प्लग कंप्यूटेशंस एक साथ' करने के लिए उपयोग कर सकते हैं - क्योंकि आप डेटाफ्लो ऑपरेशन के लिए फ़ंक्शंस लिखेंगे।नियंत्रण प्रवाह के लिए मोनाड - अनुक्रम, चयन और इटरेशन

मैं केवल इतना ही कह रहा हूं कि आप नियंत्रण प्रवाह के लिए मोनाड्स का उपयोग कर सकते हैं। अब मैं अनुक्रम, चयन और परिवर्तन के बारे में नियंत्रण प्रवाह को समझता हूं। अब मैं सूचियों पर संचालन करने के लिए मानचित्र, फ़ोल्डल, फ़िल्टर और ज़िप/मैपकैट जैसे उच्च ऑर्डर फ़ंक्शंस के साथ सहज हूं।

मेरा सवाल है - क्या मैं नियंत्रण प्रवाह प्राप्त करने के लिए monads के साथ अनुक्रम, चयन और पुनरावृत्ति कर सकता हूं?

उत्तर

5

हास्केल में अनुक्रमण के लिए (हास्केल, स्काला या Clojure में एक जवाब के लिए हैप्पी), आप कार्यों >>= और sequence:

(>>=) :: Monad m => m a -> (a -> m b) -> m b 
sequence :: Monad m => [m a] -> m [a] 

>>= या बाँध समारोह, एक monadic कार्रवाई की जाती है मूल्य के अर्क इससे और इसे एक ऐसे समारोह में खिलाता है जो एक नई monadic कार्रवाई देता है। sequence फ़ंक्शन एक ही प्रकार के मोनैडिक कार्यों की एक सूची लेता है और उन सभी को निष्पादित करता है, उनके परिणामों को जोड़ता है और इसे एक ही क्रिया के रूप में लपेटता है।

यात्रा के लिए आपके पास mapM और forM (forM = flip mapM)

mapM :: Monad m => (a -> m b) -> [a] -> m [b] 

mapM और forM काम करता है, एक समारोह कि प्रत्येक तत्व की जाने वाली कार्रवाई एक सूची में देता लागू करने के लिए एक एकल कार्रवाई के रूप में परिणाम के योग के लिए कर रहे हैं।

चयन के लिए, मुझे लगता है कि आपको सशर्त का मतलब है, जो हास्केल में लागू होते हैं, जैसे कि अन्यथा अभिव्यक्तियां। इन्हें सीधे मोनैडिक अभिव्यक्तियों में इस्तेमाल किया जा सकता है जैसा कि उन्हें शुद्ध अभिव्यक्तियों में उपयोग किया जा सकता है। हालांकि, आप विकल्पों को करने या कम से कम त्रुटियों को संभालने के लिए कुछ मोनैड का भी उपयोग कर सकते हैं।

data Maybe a = Nothing | Just a 

instance Monad Maybe where 
    return a = Just a 
    (Just a) >>= f = f a 
    Nothing >>= f = Nothing 

यह एक बहुत ही सरल कार्यान्वयन है: सबसे आसान grok की Maybe इकाई है। अनिवार्य रूप से, यदि आप किसी भी अन्य में Nothing अनुक्रमित करने का प्रयास करते हैं, तो यह हर बार Nothing वापस कर देगा।

lookup :: Eq a => a -> [(a, b)] -> Maybe b 
-- Looks up a value in a key-value association list 

myFunc :: Int -> [(String, Int)] -> Maybe Int 
myFunc mult assocList = do 
    i <- lookup "foo" assocList 
    j <- lookup "bar" assocList 
    return $ i * mult + j 

यहाँ, यदि "foo" के लिए देखने विफल रहता है, myFunc तुरंत वापस लौट Nothing: यह आपको शॉर्ट सर्किट विफलता की धारणा देता है। इसी तरह यदि "bar" के लिए लुकअप विफल रहता है, myFunc तुरंत Nothing देता है। यह केवल तब होता है जब दोनों लुकअप सफल होते हैं myFunc कोई गणना करते हैं। यह एक प्रकार का "त्रुटि प्रबंधन" प्रदान करता है। वहाँ एक समान इकाई Either a

data Either a b = Left a | Right b 

instance Monad (Either a) where 
    return a = Right a 
    (Right a) >>= f = f a 
    (Left a) >>= f = Left a 

कि इस तरह के एक स्ट्रिंग त्रुटि संदेश या विफलता के बिंदु पर गणना के राज्य के रूप में "विफलता" मूल्य को छोड़कर बहुत ज्यादा एक ही है, काम करता है कुछ संदर्भ, ले जा सकता है है।

+1

क्या '>> =' वास्तव में अनुक्रम की गारंटी देता है या यह केवल सबसे आम मोनैड का व्यवहार है? – kqr

+1

@kqr यह मूल्यांकन की अनुक्रमित करने की गारंटी नहीं देता है, अगर आप यही पूछ रहे हैं।इसका कारण यह है कि मूल्यांकन के आदेश से '(>> =)' की परिभाषा पर निर्भर करता है, और '(>> =) 'के सभी कार्यान्वयन दूसरे के पहले पहले तर्क का मूल्यांकन नहीं करते हैं। –

+0

@kqr यह अनुक्रमण की गारंटी नहीं देता है, लेकिन यह वह कार्य है जो हमें 'डू' नोटेशन का उपयोग करने की अनुमति देता है, जिसे मैंने प्रश्न के रूप में बताया है। चूंकि बाइंड अनिवार्य रूप से एक-कथन में प्रत्येक क्रिया के लिए (अंतर्निहित) अर्धविराम को परिभाषित करता है, यह हमें कोड के किसी विशेष ब्लॉक के लिए नियंत्रण प्रवाह के पहलू को परिभाषित करने का एक तरीका प्रदान करता है। – bheklilr

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