2014-09-14 8 views
5

प्रभावप्रभावशाली आवेदक प्रोग्रामिंग में अवधारणा का अर्थ क्या है?आवेदक प्रभाव क्या हैं?

उदाहरण के लिए, नीचे दिए गए भावों के कौन से हिस्से प्रभाव हैं?

[(+1)] <*> [2,3] 
Just (+1) <*> Nothing 
+2

मुझे संदेह है कि इन शर्तों का उपयोग हास्केल मानक में किया जाता है। आपके संदर्भ में उन्हें सुनना/पढ़ना उपयोगी हो सकता है। – Shoe

+0

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

उत्तर

3

बहुत भ्रम नामों की दुर्भाग्यपूर्ण पसंद के कारण हुआ था, जैसा कि हास्केल में काफी आम है ("return" सोचें, "emit" नामक बहुत बेहतर है)।

pure x नहीं शुद्ध है, यह x शुद्ध है pure सिर्फ इंजेक्षन है,। यह envisioned to be used in pure f <*> a <*> b <*> ... पैटर्न था, जो हमें प्रभावी रूप से शुद्ध फ़ंक्शन f लागू करने देता है।

आप एक घोषणा अनुप्रयोगी कि प्रत्येक मान यह हो जाता है (pure के साथ) का प्रचार करने के शहर के फाटकों के लिए एक crier भेजता है कल्पना कर सकते हैं, और जिसका लागू (<*>) प्रत्येक परिणाम यह पैदा करता है दावा करता है; तो pure x का मतलब है x जो शहर के द्वारों पर चिल्लाया गया था। प्रभाव रोना है, इसलिए pure xप्रभावशाली मान x होगा। और हम लिख सकते हैं (), यह हमारी शुद्ध भाषा में pure x के रूप में बस है।

[] अनुप्रयोगी हमें देता है "गैर निर्धारणात्मक" एक गैर नियतात्मक कार्य करने के लिए (<*>, नहीं $) एक गैर नियतात्मक मूल्य (नहीं दो मानों, अपने उदाहरण में) लागू होते हैं; गैर-निर्धारणा प्रभाव है।

सूची में आवेदक, [(+1), (+2)] एक गैर-निर्धारिती कार्य है जो 1 से एक मूल्य बढ़ा सकता है, और इसे भी बढ़ा सकता है 2. [3,4,5] एक गैर-निर्धारिती मूल्य है जिसका संभावित मूल्य सूचीबद्ध है। हम सामान्य संस्थाओं (+1) और 3 सामान्य रूप से, (+1) $ 3 के रूप में लागू होते हैं, तो हम गैर नियतात्मक मूल्यों गैर निर्धारणात्मक आवेदन कर सकते हैं, [(+1)] <*> [3] या [(+1),(+2)] <*> [3,4,5] के रूप में बस के रूप में।

और Maybeविफलता की संभावना प्रभाव है।

+0

मुझे आपकी व्याख्या पसंद है जहां 'शुद्ध' का नाम मिला है। –

+0

@ माइकलस्टेले पेपर कहता है, परिचय में: * "हम कुछ प्रभावशाली गणनाओं के मूल्य एकत्र करते हैं, जिन्हें हम शुद्ध कार्य के तर्क के रूप में उपयोग करते हैं '(:)' "*। –

5

एफपी दुनिया में, एक प्रभाव किसी भी प्रकार के निर्माता इस तरह के Maybe, [], IO, आदि के रूप प्रभाव दुष्प्रभाव के साथ भ्रमित होने की नहीं कर रहे हैं। सहजता से, प्रभाव उस मूल्य की एक अतिरिक्त संपत्ति है जिसे आप कंप्यूटिंग कर रहे हैं। Maybe Int का अर्थ है कि आपका प्रोग्राम विफलता प्रभाव के साथ Int की गणना करता है, या [Int] का अर्थ है कि आपका प्रोग्राम Int की गणना करता है लेकिन एक गैर-निर्धारिती प्रभाव के साथ (एक गैर-निर्धारिती परिणाम यहां संभावित परिणामों की सूची के रूप में मॉडलिंग किया जाता है)।

यहां से जा रहे हैं, हमारे पास मामले अनुप्रयोगी प्रभाव और monadic प्रभाव है, जो मतलब है कि ने कहा कि प्रभाव Applicative और Monad उदाहरणों की है।

मुझे इसके लिए कोई आधिकारिक जानकारी नहीं मिल रही है, यह वही है जो मैंने अपने अनुभव में प्राप्त किया है।

+0

'[]' स्वयं ही प्रभाव नहीं है, '([], शुद्ध :: ए -> [ए], (<*>) :: [ए-> बी] -> [ए] -> [बी]) ' एक प्रभाव है, 'शुद्ध' और '(<*>) के कुछ कार्यान्वयन दिए गए हैं। –

+0

@WillNess आप इसे केवल एक प्रभाव क्यों कहते हैं, न कि _applicative_ प्रभाव? मेरे अनुभव में, 'आवेदक' या 'मोनाड' के किसी भी उल्लेख के बिना, '* -> *' प्रकार के किसी भी प्रकार के कन्स्ट्रक्टर को प्रभाव कहा जाता है। –

+0

"आवेदक" यहां निहित है। :) मेरा मतलब आवेदकों के बारे में इस प्रश्न के संदर्भ में "प्रभाव" था। 'शुद्ध' और '<*>' (या 'वापसी' और '>> =') के बिना दिमाग में कार्यान्वयन, * [] 'का प्रभाव क्या है? –

5

हम कह सकते हैं कि f a का प्रभाव कुछ भी है जिसे pure x के रूप में लिखा नहीं जा सकता है, जहां x :: a

[] आवेदक, pure x = [x] में, इसलिए [(+1)] = pure (+1) शायद प्रभाव नहीं माना जाना चाहिए। इसी तरह Maybe आवेदक, pure = Just में, इसलिए Just (+1) कोई प्रभाव नहीं है।

[2,3] और Nothing आपके संबंधित उदाहरणों के प्रभाव के रूप में छोड़ देता है। यह परिप्रेक्ष्य से सहज ज्ञान देता है कि [] नोडेटर्मेनिस्टिक कंप्यूटेशंस को इंगित करता है: [2,3] nondeterministically 2 और 3 के बीच चुनता है; और परिप्रेक्ष्य कि Maybe असफल गणनाओं को दर्शाता है: Nothing गणना में विफल रहता है।

परिभाषा मैंने इसका उपयोग किया था (शायद "दुष्प्रभाव" एक बेहतर शब्द होगा) pure x के रूप में लिखा नहीं जा सकता है, जो आपके प्रश्न को सटीक बनाने के लिए सिर्फ एक स्विंग है, और किसी भी प्रकार का प्रतिनिधित्व नहीं करता है सर्वसम्मति या मानक परिभाषा का। Will Ness's answer एक अलग परिप्रेक्ष्य देता है, कि pure शुद्ध मूल्य से प्रभावशाली गणना उत्पन्न करता है, जिसमें इसकी अच्छी गणितीय अंगूठी होती है - यानी यह परिभाषा शायद सटीक सेटिंग्स में उपयोग करना आसान हो जाएगी।

+0

'शुद्ध x' शुद्ध नहीं है, यह' x' है जो शुद्ध है। परिभाषा के अनुसार, शुद्ध x' हमेशा एक प्रभावशाली 'x' है। 'शुद्ध (+1) :: [(संख्या ए) => ए-> ए]' एक प्रभावशाली वृद्धि कार्य है - एक * गैर-निर्धारिती * वृद्धि कार्य। अंतर्निहित गैर-निर्धारणा * प्रभाव * है। –

+0

मैंने अपने जवाब में जो कुछ भी मतलब था, उस पर और अधिक विस्तार करने की कोशिश की। बेशक सबकुछ हमारे पीओवी पर निर्भर करता है: हम चीजें 'कॉन्सटैप' के संदर्भ में देख सकते हैं, और हास्केल स्वयं पाठ्यक्रम की पूरी तरह से निर्धारिती है, लेकिन कभी-कभी हम गैर-निर्धारक अनुप्रयोग के संदर्भ में सोचना पसंद करते हैं। प्रभाव और दुष्प्रभावों को मिश्रण करना भी महत्वपूर्ण नहीं है, जैसा कि [नीचे एक और उत्तर] (http://stackoverflow.com/a/25838314/849891) बताता है। –

4

प्रभावी आवेदक प्रोग्रामिंग को नियमित रूप से गैर-प्रभावशाली कंप्यूटेशंस लेने और प्रभाव जोड़ने के बारे में सोचा जा सकता है। इन्हें Applicative उदाहरणों के रूप में कार्यान्वित किया गया है। इसलिए Int एक नियमित मान है, A Int कुछ प्रभाव A के साथ Int है, और AApplicative का एक उदाहरण है।

इस अभिव्यक्ति पर विचार करें:

x + y :: Int 

यह अभिव्यक्ति effectful नहीं है; यह केवल नियमित, सादे मूल्यों से संबंधित है, इसलिए बोलने के लिए। लेकिन हम प्रभावशाली जोड़ भी हो सकते हैं।

एक प्रभाव विफलता; गणना विफल या सफल हो सकती है। यदि यह विफल रहता है, तो गणना रोक दी जाती है। यह बस Maybe प्रकार है।

Just (+1) <*> Nothing :: Maybe Int 

नियमित मूल्यों के अतिरिक्त, आप केवल संख्याओं को एक साथ जोड़ते हैं। लेकिन अब, हमारे पास अतिरिक्त है जो विफल हो सकता है। तो हमें संख्याओं को जोड़ना होगा बशर्ते कि गणना विफल नहीं हुई है। हम इस अभिव्यक्ति में देखते हैं कि गणना विफल हो जाएगी, क्योंकि दूसरा ऑपरेंड Nothing है।

यदि आपकी गणना केवल एक कारण से अधिक के लिए विफल हो सकती है, तो हो सकता है कि आप त्रुटि संदेश प्राप्त करना चाहें जो कि विफलता की रिपोर्ट करता है। फिर आप त्रुटि प्रभाव का उपयोग कर सकते हैं, जिसे Either String (String जैसे त्रुटि संदेश का प्रकार) के रूप में प्रदर्शित किया जा सकता है। इस Applicative के कार्यान्वयन MaybeApplicative के समान व्यवहार करता है।

प्रभाव का एक और उदाहरण पार्सिंग है। पार्सिंग केवल रचनाकारों का उपयोग करके और उन्हें प्रभावी बनाकर कार्यान्वित किया जा सकता है। मान लें कि आप अतिरिक्त अंकगणितीय भाषा को अतिरिक्त और गुणा के साथ कार्यान्वित करना चाहते हैं।

data Exp = Num Int | Var String 
data AST = Add Exp Exp | Multiply Exp Exp 

आप बस इन निर्माताओं का उपयोग करके एएसटी का निर्माण: यह आपके सार वाक्य रचना पेड़ (एएसटी) हो सकता है। लेकिन समस्या यह है कि आपको वास्तव में पाठ को पार्स करने की भी आवश्यकता है, तो पार्सिंग के कार्य के बारे में क्या? आपने कितना पाठ खाया है इसका ट्रैक रखने के बारे में क्या? क्या होगा यदि पार्सिंग विफल हो जाती है, क्योंकि पाठ आपके व्याकरण के अनुरूप नहीं था? खैर, Parsec जैसे पुस्तकालयों में, यह पार्सिंग प्रभाव है। आप कुछ Parse डेटा प्रकार का उपयोग करते हैं (यह Applicative का उदाहरण है) और रचनाकारों को प्रभावी Parse AST दुनिया में उठाएं। अब, आप टेक्स्ट को वास्तव में पार्स करते समय एएसटी बना सकते हैं, क्योंकि पार्सिंग एएसटी के निर्माण में एक प्रभाव जोड़ा जाता है।

ध्यान दें कि Parse प्रकार Maybe और Either String दोनों उदाहरणों से अधिक जटिल था; पार्सर के पास राज्य का ट्रैक रखने के प्रभाव पड़ते हैं जैसे कि कितना इनपुट टेक्स्ट खपत किया गया है, और एक असफल पार्स, जो एक त्रुटि संदेश उत्पन्न करेगा। Applicative प्रभाव इस तरह एक साथ बना सकते हैं।

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