तीरों का उद्देश्य क्या है?


62

मैं हास्केल के साथ कार्यशील प्रोग्रामिंग सीख रहा हूं, और मैं पहले समझ द्वारा अवधारणाओं को हथियाने की कोशिश करता हूं कि मुझे उनकी आवश्यकता क्यों है।

मैं कार्यात्मक प्रोग्रामिंग भाषाओं में तीर के लक्ष्य को जानना चाहूंगा। वे किस समस्या का समाधान करते हैं? मैंने http://en.wikibooks.org/wiki/Haskell/Understand_arrows और http://www.cse.chalmers.se/~rjmh/afp-arrows.pdf की जाँच की । मैं समझता हूं कि वे अभिकलन के लिए रेखांकन का वर्णन करने के लिए उपयोग किए जाते हैं, और वे आसान बिंदु मुक्त शैली कोडिंग की अनुमति देते हैं।

लेख यह मानता है कि बिंदु मुक्त शैली आमतौर पर समझने और लिखने में आसान होती है। यह मुझे काफी सब्जेक्टिव लगता है। एक अन्य लेख ( http://en.wikibooks.org/wiki/Haskell/StephensArrowTutorial#Hangman:_Main_program ) में, एक जल्लाद गेम को लागू किया जाता है, लेकिन मैं यह नहीं देख सकता कि यह क्रियान्वयन प्राकृतिक कैसे तीर है।

मुझे अवधारणा का वर्णन करने वाले बहुत सारे पेपर मिल गए, लेकिन प्रेरणा के बारे में कुछ भी नहीं।

मुझे क्या याद आ रहा है?

जवाबों:


42

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

सबसे पहले, आप उत्पाद को एरो तक पहुंचने के बिना हास्केल में अधिकांश समस्याओं को हल कर सकते हैं। कुछ उल्लेखनीय हास्केलर्स वास्तव में पसंद नहीं करते हैं और उनका उपयोग नहीं करते हैं ( इस पर और अधिक के लिए यहां , यहां और यहां देखें )। इसलिए यदि आप अपने आप से कह रहे हैं "अरे, मुझे इनकी आवश्यकता नहीं है," यह समझें कि आप वास्तव में सही हो सकते हैं।

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

इसका सही उत्तर, जहाँ तक मैं निर्धारित कर सका हूँ, वह है: वास्तव में, हाँ। तीर के लिए अभी हत्यारे का उपयोग मामला एफआरपी है (सामान्य रूप से यमपा, खेल, संगीत और प्रतिक्रियाशील सिस्टम के बारे में सोचें)। एफआरपी के सामने आने वाली समस्या काफी हद तक एक ही समस्या है जो अन्य सभी सिंक्रोनस मैसेजिंग सिस्टम का सामना कर रही है: प्रासंगिक जानकारी या स्प्रिंगिंग लीक को छोड़ने के बिना आउटपुट की एक सतत स्ट्रीम में इनपुट की एक सतत स्ट्रीम तार कैसे करें। आप स्ट्रीम को सूची के रूप में मॉडल कर सकते हैं - कई हालिया एफआरपी सिस्टम इस दृष्टिकोण का उपयोग करते हैं - लेकिन जब आपके पास बहुत अधिक इनपुट सूची होती है तो प्रबंधन करना लगभग असंभव हो जाता है। आपको खुद को करंट से बचाने की जरूरत है।

एफआरपी सिस्टम में एरो की अनुमति क्या है, एक नेटवर्क में फ़ंक्शन की संरचना है, जबकि एक ही समय में उन कार्यों द्वारा पारित किए जा रहे अंतर्निहित मूल्यों पर किसी भी संदर्भ को पूरी तरह से अलग करना। यदि आप FP के लिए नए हैं, तो यह पहली बार भ्रमित कर सकता है, और जब आप इसके निहितार्थ को आत्मसात कर लेते हैं तो मन-बहला सकते हैं। आपने हाल ही में इस विचार को आत्मसात कर लिया है कि फ़ंक्शंस अमूर्त हो सकते हैं, और [(*), (+), (-)]प्रकार के रूप में एक सूची को कैसे समझा जाए [(a -> a -> a)]। तीर के साथ, आप अमूर्त एक परत को आगे बढ़ा सकते हैं।

अमूर्त करने की यह अतिरिक्त क्षमता इसके स्वयं के खतरों को वहन करती है। एक बात के लिए, यह जीएचसी को कोने के मामलों में धकेल सकता है जहां यह नहीं जानता कि आपके प्रकार की धारणाएं क्या हैं। आपको प्रकार के स्तर पर सोचने के लिए तैयार रहना होगा - यह प्रकार और रैंकनेट और अन्य ऐसे विषयों के बारे में जानने का एक शानदार अवसर है।

वहाँ भी कई उदाहरण हैं जो मैं "स्टुपिड एरो स्टंट्स" कहूंगा, जहां कोडर कुछ एरो कॉम्बिनेटर के लिए सिर्फ इसलिए पहुंचता है क्योंकि वह टुपल्स के साथ एक नीरस चाल दिखाना चाहता है। (यहाँ पागलपन के लिए मेरा खुद का तुच्छ योगदान है ।) जब आप जंगली में आते हैं तो ऐसे हॉट-डॉगिंग को नज़रअंदाज़ करें।

नोट: जैसा कि मैंने ऊपर उल्लेख किया है, मैं एक रिश्तेदार दोपहर हूँ। अगर मैंने ऊपर किसी भी गलत धारणा का प्रचार किया है, तो कृपया मुझे सुधारने के लिए स्वतंत्र महसूस करें।


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

जबकि तीर निश्चित रूप से आपके लिंक किए गए समाधान के लिए गलत उपकरण हैं, मुझे ऐसा लगता है कि मुझे यह उल्लेख करने की आवश्यकता है कि removeAt' n = arr(\ xs -> (xs,xs)) >>> arr (take (n-1)) *** arr (drop n) >>> arr (uncurry (++)) >>> returnAअधिक स्पष्ट और स्पष्ट रूप से लिखा जा सकता है removeAt' n = (arr (take $ n-1) &&& arr (drop n)) >>> (arr $ uncurry (++))
cemper93

29

यह एक "नरम" उत्तर की तरह है, और मुझे यकीन नहीं है कि कोई संदर्भ वास्तव में इस तरीके से बताता है, लेकिन यह है कि मैं कैसे तीरों के बारे में सोच रहा हूं:

एक तीर प्रकार A b cमूल रूप से एक फ़ंक्शन है, b -> cलेकिन उसी तरह से अधिक संरचना के साथ जिसमें M aएक सादे मूल्य में एक सादे पुराने की तुलना में अधिक संरचना होती है a

अब जो अतिरिक्त संरचना होती है वह उस विशेष तीर उदाहरण पर निर्भर करती है, जिसके बारे में आप बात कर रहे हैं। बस के रूप में भिक्षुओं IO aऔर Maybe aप्रत्येक के पास अलग-अलग अतिरिक्त संरचना होती है।

बात यह है कि आप monads साथ मिल एक से जाना करने में असमर्थता है M aएक करने के लिए a। अब यह एक सीमा की तरह लग सकता है, लेकिन यह वास्तव में एक विशेषता है: प्रकार प्रणाली आपको एक सामान्य मूल्य को एक सादे मूल्य में बदलने से बचा रही है। आप केवल मोनाद के माध्यम से >>=या विशेष सन्यासी उदाहरण के आदिम संचालन में भाग लेकर मूल्य का उपयोग कर सकते हैं ।

इसी तरह जो चीज आपको मिलती है, A b cवह एक नए बी-उपभोग वाले सी-उत्पादक "फ़ंक्शन" का निर्माण करने में असमर्थता है। तीर आपको उपभोग करने से बचा रहा है bऔर cविभिन्न तीर कोमिनेटरों में भाग लेने या विशेष तीर उदाहरण के आदिम संचालन का उपयोग करके एक अपवाद को छोड़कर।

उदाहरण के लिए यमपा में सिग्नल फ़ंक्शन लगभग मोटे तौर पर हैं (Time -> a) -> (Time -> b), लेकिन इसके अलावा उन्हें एक निश्चित कार्य-कारण प्रतिबंध का पालन करना होगा : समय पर आउटपुट tइनपुट सिग्नल के पिछले मूल्यों से निर्धारित होता है: आप भविष्य में नहीं देख सकते हैं। तो वे क्या करते हैं इसके बजाय प्रोग्रामिंग के साथ (Time -> a) -> (Time -> b), आप के साथ प्रोग्राम करते हैं SF a bऔर आप अपने सिग्नल फ़ंक्शंस का निर्माण करते हैं। ऐसा होता है कि चूंकि SF a bएक फ़ंक्शन की तरह बहुत कुछ व्यवहार करता है, इसलिए कि सामान्य संरचना को "तीर" कहा जाता है।


"तीर आपको उपभोग करने से बचा रहा है bऔर cविभिन्न तीर के कॉम्बिनेटरों में भाग लेने या विशेष तीर उदाहरण के आदिम संचालन का उपयोग करके एक अपवाद को छोड़कर।" इस प्राचीन उत्तर का जवाब देने के लिए माफी के साथ: इस वाक्य ने मुझे रैखिक प्रकारों के बारे में सोचा, अर्थात संसाधनों का क्लोन या गायब नहीं किया जा सकता है। क्या आपको लगता है कि कोई संबंध हो सकता है?
ग्लोबोहेरल

14

मुझे तीरंदाजों के बारे में सोचना पसंद है, जैसे मोनाड्स और फ़ंक्टर, प्रोग्रामर को कार्यों की विदेशी रचनाओं को करने की अनुमति देते हैं।

मोनाड्स या एरो (और फ़ंक्टर) के बिना, एक कार्यात्मक भाषा में कार्यों की संरचना एक फ़ंक्शन को दूसरे फ़ंक्शन के परिणाम में लागू करने तक सीमित है। मोनाड्स और फ़ंक्शनलर्स के साथ, आप दो फ़ंक्शंस को परिभाषित कर सकते हैं, और फिर अलग-अलग पुन: प्रयोज्य कोड लिख सकते हैं जो निर्दिष्ट करते हैं कि कैसे उन फ़ंक्शंस, विशेष रूप से मोनड के संदर्भ में, एक-दूसरे के साथ और उन डेटा के साथ बातचीत करते हैं जो उनमें पारित हो जाते हैं। यह कोड मोनाड के बाइंड कोड के भीतर रखा गया है। तो एक मठ एक दृश्य है, बस पुन: प्रयोज्य बाँध कोड के लिए एक कंटेनर है। एक संन्यासी दूसरे संन्यासी के संदर्भ में अलग-अलग तरीके से रचनाएँ करता है।

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

मोनाड्स का अर्थ यह भी है कि प्रोग्रामर को स्पष्ट रूप से उन मापदंडों को टाइप करने की आवश्यकता नहीं होती है जो प्रत्येक फ़ंक्शन को स्रोत कोड में आवश्यक होते हैं - बाइंड फ़ंक्शन पैरामीटर पासिंग। इसलिए मोनड्स का उपयोग करते हुए, स्रोत कोड फ़ंक्शन नामों के स्थिर श्रृंखला की तरह अधिक दिखना शुरू कर सकता है, बजाय यह देखने के कि कि फ़ंक्शन A "कॉल" फ़ंक्शन B को पैरामीटर C और D के साथ क्या करता है - कोड एक इलेक्ट्रॉनिक सर्किट की तरह अधिक महसूस करना शुरू कर देता है चलती मशीन - अनिवार्यता से अधिक कार्यात्मक।

एरो भी फ़ंक्शन को एक साथ बाँध फ़ंक्शन के साथ जोड़ता है, पुन: प्रयोज्य कार्यक्षमता प्रदान करता है और मापदंडों को छिपाता है। लेकिन एरो खुद को एक साथ जुड़ा और रचा जा सकता है, और वैकल्पिक रूप से रनटाइम पर अन्य एरो को डेटा रूट कर सकता है। अब आप डेटा को एरो के दो रास्तों पर लागू कर सकते हैं, जो डेटा को "अलग-अलग काम करते हैं" और परिणाम को फिर से इकट्ठा करते हैं। या आप डेटा में कुछ मूल्य के आधार पर डेटा को पास करने के लिए एरो की किस शाखा का चयन कर सकते हैं। परिणामी कोड एक इलेक्ट्रॉनिक सर्किट की तरह और भी अधिक है, जिसमें स्विचेस, देरी, एकीकरण आदि हैं। कार्यक्रम बहुत स्थिर दिखता है, और आपको डेटा के बहुत अधिक हेरफेर को देखने में सक्षम नहीं होना चाहिए। इसके बारे में सोचने के लिए कम और कम पैरामीटर हैं, और यह सोचने की ज़रूरत नहीं है कि पैरामीटर क्या मान सकते हैं या नहीं ले सकते हैं।

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

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


लेकिन यह एक ऐप्लिकेटर फ़ंक्टर की तरह लगता है (एक फ़ंक्शन के आसपास कुछ रैपर, जो कुछ विशिष्ट संदर्भ में सहायक कार्य प्रदान करता है, लिपटे-प्रकार के लिए पहले से मौजूद कार्यों का पुन: उपयोग करने के लिए)। मुझे समझने के लिए निश्चित रूप से और अधिक पढ़ने की आवश्यकता है, लेकिन शायद आप मदद कर सकते हैं, जो मुझे याद आ रही है यह इंगित करके
बेलुन

3

अन्य उत्तरों के अतिरिक्त: व्यक्तिगत रूप से यह समझने में मुझे बहुत मदद मिलती है कि ऐसी अवधारणा क्या है (गणितीय रूप से) और यह अन्य अवधारणाओं से कैसे संबंधित है, जो मुझे पता है।

तीरों के मामले में, मुझे निम्नलिखित पेपर मददगार लगे - यह मोनडेस, ऐप्लीकेशनल फंक्शनलर्स (मुहावरों) और तीरों की तुलना करता है: मुहावरे अनजान होते हैं, तीर सावधानीपूर्वक होते हैं, सैम लिंडली, फिल्ड वाडलर और जेरेमी यलोप द्वारा मोनड्स को बढ़ावा दिया जाता है

इसके अलावा मेरा मानना ​​है कि किसी ने भी इस लिंक का उल्लेख नहीं किया है जो आपको इस विषय पर कुछ विचार और साहित्य प्रदान कर सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.