2013-01-10 17 views
15

someFun <$> (a :: IO()) <$> (b :: IO()) द्वारा परिभाषित आईओ क्रिया को निष्पादित करते समय, a और b क्रियाओं का निष्पादन निष्पादित किया गया है? यही है, क्या मैं a पर b से पहले निष्पादित कर सकता हूं?हास्केल - आवेदक के मामले में प्रभाव आदेश निर्धारक है?

जीएचसी के लिए, मैं देख सकता हूं कि आईओ राज्य का उपयोग करके लागू किया गया है, और यह भी here देखता है कि यह एक आवेदक उदाहरण है, लेकिन वास्तविक उदाहरण घोषणा का स्रोत नहीं मिल सकता है। राज्य के माध्यम से लागू किए जाने से पता चलता है कि विभिन्न आईओ प्रभावों को अनुक्रमिक होने की आवश्यकता है, लेकिन आवश्यक नहीं है कि वे अपने आदेश को परिभाषित करें।

जीएचसीआई में चारों ओर बजाना लगता है कि एप्लायेटिव प्रभाव आदेश को बरकरार रखता है, लेकिन क्या यह कुछ सार्वभौमिक गारंटी है, या जीएचसी विशिष्ट है? मुझे विवरण में दिलचस्पी होगी।

import System.Time 
import Control.Concurrent 
import Data.Traversable 
let prec (TOD a b) = b 
fmap (map prec) (sequenceA $ replicate 5 (threadDelay 1000 >> getClockTime)) 

[641934000000,642934000000,643934000000,644934000000,645934000000] 

धन्यवाद!

+0

मुझे लगता है कि इस पोस्ट में उपयोगी जानकारी है लेकिन मुझे अभी भी इसे पचाना है: http://pchiusano.blogspot.hu/2011/07/do-side-effects-really-need-total-order.html – ron

+4

http देखें : //hackage.haskell.org/packages/archive/transformers/0.3.0.0/doc/html/Control-Aplicative-Backwards.html, जो एक आवेदक ट्रांसफार्मर है जो प्रभाव के क्रम को उलट देता है। –

उत्तर

18

यह निश्चित रूप से निर्धारक, हां है। यह किसी भी विशिष्ट उदाहरण के लिए हमेशा एक ही बात करेगा। हालांकि, निहित प्रभाव के क्रम के लिए बाएं से दाएं दाएं से बाएं चुनने का कारण नहीं है।

हालांकि, the documentation for Applicative से:

तो f भी एक Monad है, यह पूरा करना चाहिए pure = return और (<*>) = ap (जिसका मतलब है कि pure और <*> अनुप्रयोगी functor कानूनों को संतुष्ट)।

ap की परिभाषा यह है, Control.Monad से:

ap :: (Monad m) => m (a -> b) -> m a -> m b 
ap = liftM2 id 

और liftM2 स्पष्ट तरीके से परिभाषित किया गया है:

liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) } 

इसका मतलब क्या है कि है, किसी भी functor है कि के लिए Monad के साथ-साथ Applicative, यह अपेक्षा की जाती है (विनिर्देशन के अनुसार, क्योंकि इसे कोड में लागू नहीं किया जा सकता है), Applicative बाएं से दाएं काम करेगा, ताकि liftM2 में ब्लॉक liftA2 f x y = f <$> x <*> y जैसा ही काम करता है।

उपर्युक्त के कारण, Applicative के लिए Monad के बिना उदाहरण के लिए, प्रभावों को आम तौर पर बाएं से दाएं आदेश दिया जाता है।

अधिक मोटे तौर पर, क्योंकि एक Applicative गणना की संरचना "प्रभाव" जरूरी स्वतंत्र है, आप आमतौर पर एक कार्यक्रम का अर्थ कैसे Applicative प्रभाव अनुक्रम कर रहे हैं की स्वतंत्र रूप से विश्लेषण कर सकते हैं। उदाहरण के लिए, यदि [] के लिए उदाहरण क्रमशः अनुक्रम में बदल दिया गया था, तो इसका उपयोग करने वाला कोई भी कोड उसी परिणाम देगा, केवल अलग-अलग क्रम में सूची तत्वों के साथ।

+0

धन्यवाद! क्या मैं सही ढंग से अनुमान लगाता हूं कि यदि मेरे लिए प्रभाव आदेश महत्वपूर्ण है और मैं सैद्धांतिक होना चाहता हूं तो मुझे एक मोनाड का उपयोग करना चाहिए, लेकिन यदि मैं व्यावहारिक हूं तो एक आवेदक (आमतौर पर, देखभाल के साथ) फिट होगा? – ron

+2

@ron: प्रैक्टिस में, आप बस यह मान सकते हैं कि 'आवेदक' उदाहरण बाएं से दाएं अनुक्रमित किए जाएंगे जब तक कि वे 'पिछड़ा' रैपर के साथ अन्यथा जोर से घोषणा न करें। ध्यान दें कि 'मोनाड' उदाहरण अन्य तरीकों से अस्पष्ट भी हो सकते हैं - उदाहरण के लिए, उलट 'राज्य' मोनैड राज्य मूल्य को पीछे की तरफ थ्रेड करता है, लेकिन यह प्रकार नियमित रूप से 'राज्य' के समान होता है। एक और उदाहरण के लिए, अनुक्रमित क्रम से भी '[] 'में दो संभव' आवेदक 'उदाहरण हैं। दस्तावेज कहता है कि आप कुछ हद तक भरोसा नहीं कर सकते हैं। –

+0

@ सीए.एमसीकैन "* [...] आप आमतौर पर प्रोग्राम के अर्थ का स्वतंत्र रूप से विश्लेषण कर सकते हैं कि आवेदक प्रभाव कैसे अनुक्रमित होते हैं। *" क्यों? क्या यह * कम्यूटिव * आवेदक फंक्चरर्स के लिए ही सही नहीं है? आम तौर पर, पुनर्नवीनीकरण लागू प्रभाव नाटकीय रूप से परिणाम बदल सकते हैं। यहां एक उदाहरण दिया गया है: 'myParser = (++) <$> foo <*> बार' जहां' foo' और 'bar' parsec 'पार्सर स्ट्रिंग' हैं। अगर मैंने अनुक्रम को दाएं से बाएं में बदल दिया है, तो 'myParser' इनपुट स्ट्रिंग' 'foobar' 'पर असफल हो जाएगा। क्या आप सहमत नहीं होंगे, इस मामले में, प्रभावों के पुनर्मूल्यांकन ने कार्यक्रम के अर्थ को प्रभावित किया है? – Jubobs

4

हां, आदेश मोनाड-आवेदक पत्राचार द्वारा पूर्वनिर्धारित है।यह देखना आसान है: (*>) Combinator एक इकाई के लिए एक अच्छी तरह से व्यवहार Applicative उदाहरण में (>>) Combinator के अनुरूप करने की जरूरत है, और इसकी परिभाषा है:

a *> b = liftA2 (const id) a b 

दूसरे शब्दों में, अगर ba से पहले मार डाला गया, Applicative उदाहरण बीमार व्यवहार होगा।

संपादित करें: एक पक्ष नोट के रूप में: यह स्पष्ट रूप से कहीं भी निर्दिष्ट नहीं है, लेकिन आप liftM2 = liftA2 जैसे कई अन्य इसी तरह के पत्राचार पा सकते हैं, आदि

2

आईओ अनुप्रयोगी के लिए, यह निश्चित रूप से मामला है। लेकिन को एक आवेदक के उदाहरण के लिए देखें जहां f <$> a <*> ba और b के प्रभाव समानांतर में होते हैं।

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