2011-11-23 10 views
22

मुझे परेशान है। मैं इसे लिख सकता हूं:तह, फंक्शन संरचना, मोनैड, और आलस्य, ओह मेरे?

import Control.Monad 

main = print $ head $ (foldr (.) id [f, g]) [3] 
    where f = (1:) 
     g = undefined 

और आउटपुट 1 है। यही कारण है कि समझ में आता है, क्योंकि यह करने के लिए कम कर देता है:

main = print $ head $ ((1:) . undefined . id) [3] 
main = print $ head $ (1:) ((undefined . id) [3]) 
main = print $ head $ 1 : ((undefined . id) [3]) 
main = print $ 1 

लेकिन अगर मैं एक अस्पष्ट समान monadic तकनीक का उपयोग करें, यह एक ही काम नहीं करता:

import Control.Monad 

main = print $ (foldr (<=<) return [f, g]) 3 
    where f = const Nothing 
     g = undefined 

यह prelude.Undefined पूरी करता है। कौन सा, अजीब है क्योंकि मैं इसे कम करने के लिए उम्मीद करेंगे:

main = print $ ((const Nothing) <=< undefined <=< return) 3 
main = print $ return 3 >>= undefined >>= (\_ -> Nothing) 
main = print $ Nothing -- nope! instead, undefined makes this blow up 

हालांकि, रचना के आदेश flipping:

import Control.Monad 

main = print $ (foldr (>=>) return [f, g]) 3 
    where f = const Nothing 
     g = undefined 

की उम्मीद कम सर्किटिंग पूरा करता है और Nothing पैदा करता है।

main = print $ (const Nothing >=> undefined >=> return) 3 
main = print $ (const Nothing 3) >>= undefined >>= return 
main = print $ Nothing >>= undefined >>= return 
main = print $ Nothing 

मैं दो दृष्टिकोण की तुलना मान लें कि हो सकता है किया गया की तुलना सेब और संतरे है, लेकिन आप अंतर की व्याख्या कर सकते? मैंने सोचा कि f <=< gf . g पर मोनैडिक एनालॉग था, लेकिन जाहिर है, जैसा कि मैंने सोचा था उतना ही वैसा ही नहीं है। क्या आप व्यख्या कर सकते हैं?

उत्तर

20

यह इस बात पर निर्भर करता है कि आप किस मोनैड के साथ काम कर रहे हैं, और इसके (>>=) ऑपरेटर को कैसे परिभाषित किया गया है।

Maybe के मामले में, (>>=) अपने पहले तर्क में सख्त है, क्योंकि डैनियल फिशर ने समझाया।

यहां कुछ अन्य मोनैड के लिए कुछ परिणाम दिए गए हैं।

> :set -XNoMonomorphismRestriction 
> let foo = (const (return 42) <=< undefined <=< return) 3 
> :t foo 
foo :: (Num t, Monad m) => m t 

पहचान: लेज़ी।

> Control.Monad.Identity.runIdentity foo 
42 

आईओ: सख्त।

> foo :: IO Integer 
*** Exception: Prelude.undefined 

रीडर: लेज़ी।

> Control.Monad.Reader.runReader foo "bar" 
42 

लेखक: दोनों एक आलसी और एक सख्त संस्करण है।

> Control.Monad.Writer.runWriter foo 
(42,()) 
> Control.Monad.Writer.Strict.runWriter foo 
*** Exception: Prelude.undefined 

राज्य: भी दोनों एक सख्त और एक आलसी संस्करण है।

> Control.Monad.State.runState foo "bar" 
(42,"*** Exception: Prelude.undefined 
> Control.Monad.State.Strict.runState foo "bar" 
*** Exception: Prelude.undefined 

शेष भाग: सख्त।

> Control.Monad.Cont.runCont foo id 
*** Exception: Prelude.undefined 
19

Maybe के लिए बाध्य पहले तर्क में सख्त है।

Just v >>= f = f v 
Nothing >>= f = Nothing 

तो तुम कोशिश

Just v >>= undefined >>= \_ -> Nothing 

आप

undefined v >>= \_ -> Nothing 

मारा और कार्यान्वयन पता लगाएँ कि क्या undefined vNothing या Just something(>>=) का जो समीकरण का उपयोग करने को देखने के लिए है खोजने के लिए की जरूरत है जब।

दूसरी ओर,

Nothing >>= undefined 

(>>=) का दूसरा तर्क को देखे बिना परिणाम निर्धारित करता है।

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