C # में, एक साधु क्या है?


190

इन दिनों भिक्षुओं को लेकर काफी चर्चा है। मैंने कुछ लेख / ब्लॉग पोस्ट पढ़े हैं, लेकिन अवधारणा को पूरी तरह समझने के लिए मैं उनके उदाहरणों से बहुत दूर नहीं जा सकता। इसका कारण यह है कि मठ एक कार्यात्मक भाषा अवधारणा है, और इस प्रकार उदाहरण उन भाषाओं में हैं, जिनके साथ मैंने काम नहीं किया है (क्योंकि मैंने एक कार्यात्मक भाषा का गहराई से उपयोग नहीं किया है)। लेखों का पूरी तरह से पालन करने के लिए मैं वाक्य रचना को गहराई से समझ नहीं सकता ... लेकिन मैं बता सकता हूं कि वहां कुछ समझने लायक है।

हालाँकि, मैं C # बहुत अच्छी तरह से जानता हूं, जिसमें लैम्ब्डा एक्सप्रेशन और अन्य कार्यात्मक विशेषताएं शामिल हैं। मुझे पता है कि C # में केवल कार्यात्मक विशेषताओं का एक सबसेट है, और इसलिए शायद C # में मठों को व्यक्त नहीं किया जा सकता है।

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

धन्यवाद!

(EDIT: वैसे, मुझे पता है कि SO पर पहले से ही कम से कम 3 "एक सन्यासी क्या है" प्रश्न हैं। हालांकि, मैं उनके साथ एक ही समस्या का सामना करता हूं ... इसलिए इस प्रश्न की आवश्यकता imo है, क्योंकि C # -developer ध्यान दें। धन्यवाद।)


कृपया ध्यान दें कि यह वास्तव में C # 3.0 डेवलपर है। इसे .NET 3.5 के साथ गलती न करें। इसके अलावा, अच्छा सवाल है।
रज्जी

4
यह इंगित करने योग्य है कि LINQ क्वेरी अभिव्यक्तियाँ C # 3. में उन्मादी व्यवहार का एक उदाहरण हैं
Erik Forbes

1
मुझे अभी भी लगता है कि यह एक दोहरा प्रश्न है। में जवाब में से एक stackoverflow.com/questions/2366/can-anyone-explain-monads से लिंक channel9vip.orcsweb.com/shows/Going+Deep/... , जहां टिप्पणियों में से एक एक बहुत अच्छी सी # उदाहरण है। :)
जलफ

4
फिर भी, यह एसओ सवालों के एक जवाब से सिर्फ एक लिंक है। मुझे C # डेवलपर्स पर केंद्रित प्रश्न में मूल्य दिखाई देता है। यह कुछ ऐसा है जो मैं एक कार्यात्मक प्रोग्रामर से पूछूंगा जो C # करता था अगर मुझे एक पता था, तो यह SO पर पूछने के लिए उचित लगता है। लेकिन मैं आपकी राय के साथ-साथ आपके अधिकार का भी सम्मान करता हूं।
चार्ली फूल

1
एक जवाब नहीं है, हालांकि आप सभी की जरूरत है? ;) मेरा कहना सिर्फ इतना है कि अन्य प्रश्नों में से एक (और अब यह एक भी है, इसलिए याय) के पास एक सी # -स्पेशल उत्तर है (जो वास्तव में अच्छी तरह से लिखा गया है, वास्तव में। संभवतः सबसे अच्छा स्पष्टीकरण मैंने देखा है)
जलफ।

जवाबों:


147

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

एक संन्यासी यह "गणनाओं के संयोजन" को करने का कोई तरीका है।

आमतौर पर आपका सबसे बुनियादी "ऑपरेटर" दो संगणनाओं को एक साथ जोड़ना है ;:

a; b

जब आप कहते हैं कि इसका मतलब है "पहले करो a, फिर करो b"। परिणाम a; bमूल रूप से फिर से एक संगणना है जिसे अधिक सामान के साथ जोड़ा जा सकता है। यह एक साधारण मोनाड है, यह बड़े लोगों के लिए छोटे कम्प्यूटेशंस का मुकाबला करने का एक तरीका है। ;कहते हैं, "बाईं तरफ के काम करते हैं, तो सही पर काम करते हैं।"

एक और बात है कि वस्तु उन्मुख भाषाओं में एक सन्यासी के रूप में देखा जा सकता है .। अक्सर आप इस तरह की चीजें पाते हैं:

a.b().c().d()

.मूल रूप से इसका मतलब है "बाईं तरफ गणना का मूल्यांकन, और फिर उस के परिणाम पर सही पर विधि कहते हैं"। यह फ़ंक्शन / संगणनाओं को एक साथ संयोजित करने का एक और तरीका है, थोड़ा अधिक जटिल है ;। और चीजों को एक साथ जोड़ने की अवधारणा .एक सनक है, क्योंकि यह एक नई संगणना के साथ दो संगणनाओं के संयोजन का एक तरीका है।

एक और काफी सामान्य मठ, जिसमें कोई विशेष वाक्यविन्यास नहीं है, यह पैटर्न है:

rv = socket.bind(address, port);
if (rv == -1)
  return -1;

rv = socket.connect(...);
if (rv == -1)
  return -1;

rv = socket.send(...);
if (rv == -1)
  return -1;

-1 का रिटर्न वैल्यू विफलता को इंगित करता है, लेकिन इस त्रुटि की जाँच करने का कोई वास्तविक तरीका नहीं है, भले ही आपके पास बहुत सारे एपीआई-कॉल हों जिन्हें आपको इस फैशन में संयोजित करने की आवश्यकता है। यह मूल रूप से सिर्फ एक और मोनाड है जो फ़ंक्शन कॉल को नियम से जोड़ता है "यदि बाईं ओर फ़ंक्शन -1 लौटता है, तो स्वयं -1 वापस करें, अन्यथा फ़ंक्शन को दाईं ओर कॉल करें"। अगर हमारे पास एक ऑपरेटर होता >>=जो यह काम करता तो हम बस लिख सकते थे:

socket.bind(...) >>= socket.connect(...) >>= socket.send(...)

यह चीजों को अधिक पठनीय बनाता है और संयोजन कार्यों के हमारे विशेष तरीके को बाहर करने में मदद करता है, ताकि हमें खुद को बार-बार दोहराने की आवश्यकता न हो।

और फ़ंक्शंस / कम्प्यूटेशंस को संयोजित करने के कई और तरीके हैं जो एक सामान्य पैटर्न के रूप में उपयोगी हैं और एक मोनड में अमूर्त किया जा सकता है, जिससे मोनड के उपयोगकर्ता को अधिक संक्षिप्त और स्पष्ट कोड लिखने के लिए सक्षम किया जा सकता है, क्योंकि सभी बुक-कीपिंग और प्रबंधन उपयोग किए गए कार्यों को मोनाड में किया जाता है।

उदाहरण के लिए उपरोक्त >>=को "त्रुटि जाँच करने और फिर इनपुट के रूप में मिला सॉकेट पर दाईं ओर कॉल" करने के लिए बढ़ाया जा सकता है, ताकि हमें socketबहुत बार स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता न हो :

new socket() >>= bind(...) >>= connect(...) >>= send(...);

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


28
बहुत बढ़िया जवाब! मैं ओलिवर स्टील के एक उद्धरण में फेंकने जा रहा हूं, मोनाड्स को ऑपरेटर के साथ ला ला सी + या C # से लोड करने की कोशिश कर रहा हूं: मोनाड्स आपको 'ओवरलोड' करने की अनुमति देता है; ऑपरेटर।
जोर्ग डब्ल्यू मित्तग

6
@ JörgWMittag मैंने वह बोली पहले पढ़ी थी, लेकिन यह बहुत ज्यादा बकवास लग रहा था। अब जब मैं भिक्षुओं को समझता हूं और इस विवरण को पढ़ता हूं कि ';' एक है, मैं समझ गया। लेकिन मुझे लगता है कि यह वास्तव में सबसे जरूरी डेवलपर्स के लिए एक तर्कहीन बयान है। ';' एक ऑपरेटर के रूप में नहीं देखा जाता है // से सबसे अधिक है।
जिमी हॉफ

2
क्या आप सुनिश्चित हैं कि आप जानते हैं कि एक सन्यासी क्या है? मोनाड्स "फ़ंक्शन" या संगणना नहीं है, मोनाड्स के लिए नियम हैं।
लुइस

आपके ;उदाहरण में: किन वस्तुओं / डेटा प्रकारों का ;नक्शा होता है? (लगता है कि Listनक्शे Tके लिए List<T>) कैसे काम करता है ;के बीच वस्तुओं / डेटा प्रकार नक्शा morphisms / कार्य? क्या है pure, join, bindके लिए ;?
मीका विडेनमैन

44

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

और कल रात, मैं आया और इन प्रतिक्रियाओं को फिर से पढ़ा। सबसे महत्वपूर्ण बात , मैंने ब्रायन बेकमैन वीडियो के पाठ टिप्पणियों में विशिष्ट C # उदाहरण को फिर से पढ़ा, जिसका उल्लेख ऊपर किसी ने किया है । यह पूरी तरह से स्पष्ट और रोशन था कि मैंने इसे सीधे यहां पोस्ट करने का फैसला किया है।

इस टिप्पणी के कारण, न केवल मुझे ऐसा लगता है कि मैं ठीक से समझता हूं कि मोनाड्स क्या हैं ... मुझे लगता है कि मैंने वास्तव में सी # में कुछ चीजें लिखी हैं जो मोनाड हैं ... या कम से कम बहुत करीब हैं, और समान समस्याओं को हल करने का प्रयास करते हैं।

तो, यहाँ टिप्पणी है - यह सब सिलेन द्वारा यहाँ टिप्पणी से एक सीधा उद्धरण है :

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

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

ठीक है, इसलिए सबसे आसान मोनड्स में से एक को हास्केल में "शायद मोनड" कहा जाता है। C # में शायद प्रकार को कहा जाता है Nullable<T>। यह मूल रूप से एक छोटा वर्ग है जो सिर्फ एक मूल्य की अवधारणा को एनकैप्सुलेट करता है जो या तो मान्य है और जिसका मूल्य है, या "शून्य" है और जिसका कोई मूल्य नहीं है।

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

यहां वह कार्यक्रम है जो पूरी चीज को प्रेरित करता है (मैं Bindबाद में परिभाषित करूंगा , यह सिर्फ आपको यह दिखाने के लिए है कि यह अच्छा क्यों है)।

 class Program
    {
        static Nullable<int> f(){ return 4; }        
        static Nullable<int> g(){ return 7; }
        static Nullable<int> h(){ return 9; }


        static void Main(string[] args)
        {
            Nullable<int> z = 
                        f().Bind( fval => 
                            g().Bind( gval => 
                                h().Bind( hval =>
                                    new Nullable<int>( fval + gval + hval ))));

            Console.WriteLine(
                    "z = {0}", z.HasValue ? z.Value.ToString() : "null" );
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    }

अब, एक पल के लिए नजरअंदाज करें कि NullableC # के लिए ऐसा करने के लिए पहले से ही समर्थन है (आप एक साथ अशक्त ints जोड़ सकते हैं और यदि आप अशक्त हैं तो आप अशक्त हो जाते हैं)। आइए दिखाते हैं कि ऐसी कोई विशेषता नहीं है, और यह केवल एक उपयोगकर्ता-परिभाषित वर्ग है जिसमें कोई विशेष जादू नहीं है। मुद्दा यह है कि हम Bindकिसी वैरिएबल को हमारे Nullableमान की सामग्री से बाँधने के लिए फ़ंक्शन का उपयोग कर सकते हैं और फिर दिखावा कर सकते हैं कि कुछ अजीब नहीं चल रहा है, और उन्हें सामान्य ints की तरह उपयोग करें और बस उन्हें एक साथ जोड़ें। हम अंत में एक नल में परिणाम लपेट, और कहा कि नल या तो (यदि कोई अशक्त हो जाएगा f, gया hरिटर्न नल) या यह संक्षेप का परिणाम हो जाएगा f, gऔरhसाथ में। (यह कैसे हम डेटाबेस में एक पंक्ति को LINQ में एक चर में बाँध सकते हैं, और इसके साथ सामान करते हैं, इस ज्ञान में सुरक्षित है कि Bindऑपरेटर यह सुनिश्चित कर लेगा कि चर केवल मान्य पंक्ति मानों को पारित किया जाएगा।

आप इस के साथ खेल सकते हैं और कोई भी परिवर्तन f, gऔर hअशक्त वापस जाने के लिए और आपको लगता है कि पूरी बात वापस आ जाएगी अशक्त देखेंगे।

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

यहाँ Bindऑपरेटर है:

public static Nullable<B> Bind<A,B>( this Nullable<A> a, Func<A,Nullable<B>> f ) 
    where B : struct 
    where A : struct
{
    return a.HasValue ? f(a.Value) : null;
}

वीडियो में यहाँ के प्रकार ठीक हैं। इसमें M a ( Nullable<A>इस केस के लिए C # सिंटैक्स में) और ( C # सिंटैक्स में) से एक फंक्शन होता aहै , और यह एक ( ) रिटर्न देता है ।M bFunc<A, Nullable<B>>M bNullable<B>

कोड बस जाँच करता है कि क्या अशक्त का कोई मान है और यदि वह इसे निकालता है और इसे फ़ंक्शन पर पास करता है, तो यह केवल शून्य देता है। इसका मतलब यह है कि Bindऑपरेटर हमारे लिए सभी शून्य-जाँच तर्क को संभाल लेगा। यदि और केवल अगर हम जिस मूल्य Bindपर कॉल करते हैं वह गैर-अशक्त है, तो वह मान लंबोदा फ़ंक्शन के साथ "पास" किया जाएगा, अन्यथा हम जल्दी बाहर निकलते हैं और पूरी अभिव्यक्ति शून्य है। इस कोड है कि हम इकाई का उपयोग कर लिखने के इस अशक्त की जाँच व्यवहार की पूरी तरह से मुक्त होने के लिए, हम बस का उपयोग की अनुमति देता है Bindऔर एक चर monadic मूल्य के अंदर मूल्य के लिए बाध्य मिल ( fval, gvalऔर hvalउदाहरण कोड में) और हम उन्हें सुरक्षित उपयोग कर सकते हैं ज्ञान में जो Bindउन्हें पास करने से पहले अशक्त के लिए जाँच करने का ध्यान रखेगा।

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

अंत में, यहां हास्केल में एक ही कोड का कार्यान्वयन ( -- एक टिप्पणी लाइन शुरू होता है) है।

-- Here's the data type, it's either nothing, or "Just" a value
-- this is in the standard library
data Maybe a = Nothing | Just a

-- The bind operator for Nothing
Nothing >>= f = Nothing
-- The bind operator for Just x
Just x >>= f = f x

-- the "unit", called "return"
return = Just

-- The sample code using the lambda syntax
-- that Brian showed
z = f >>= ( \fval ->
     g >>= ( \gval ->  
     h >>= ( \hval -> return (fval+gval+hval ) ) ) )

-- The following is exactly the same as the three lines above
z2 = do 
   fval <- f
   gval <- g
   hval <- h
   return (fval+gval+hval)

जैसा कि आप doअंत में अच्छा अंकन देख सकते हैं यह सीधे अनिवार्य कोड जैसा दिखता है। और वास्तव में यह डिजाइन द्वारा है। मोनाड्स को अनिवार्य प्रोग्रामिंग (म्यूटेबल स्टेट, आईओ आदि) में सभी उपयोगी सामानों को एनकैप्सुलेट करने के लिए इस्तेमाल किया जा सकता है और इस अच्छे अनिवार्य जैसे सिंटैक्स का उपयोग किया जा सकता है, लेकिन पर्दे के पीछे, यह सिर्फ मोनैड्स और द्विआधारी ऑपरेटर का चतुर कार्यान्वयन है! अच्छी बात यह है कि आप अपने स्वयं के भिक्षुओं को लागू करके >>=और लागू कर सकते हैं return। और यदि आप ऐसा करते हैं, तो वे लोग भी doसंकेतन का उपयोग करने में सक्षम होंगे , जिसका अर्थ है कि आप मूल रूप से केवल दो कार्यों को परिभाषित करके अपनी छोटी भाषाएं लिख सकते हैं!


3
व्यक्तिगत रूप से मैं मोनाद के एफ # संस्करण को पसंद करता हूं, लेकिन किसी भी मामले में वे कमाल के हैं।
चोसपंडियन

3
यहाँ वापस आने और अपनी पोस्ट को अपडेट करने के लिए धन्यवाद। यह ऐसे फॉलो-अप हैं जो प्रोग्रामर की मदद करते हैं, जो एक विशिष्ट क्षेत्र में देख रहे हैं, वास्तव में समझते हैं कि साथी प्रोग्रामर ने आखिरकार कहा कि क्षेत्र के संबंध में, केवल "मैं y तकनीक में x कैसे करता हूं" के बजाय जाने के लिए। आप एक आदमी!
कप्पिम्स

मैंने वही रास्ता लिया है जो आपने मूल रूप से लिया है और एक ही जगह पर पहुंचे हैं, जो कि मोनाड्स को समझ रहे हैं, उन्होंने कहा कि यह एक मोनाड के बाध्यकारी व्यवहार का सबसे अच्छा विवरण है जिसे मैंने कभी भी एक अनिवार्य डेवलपर के लिए देखा है। हालांकि मुझे लगता है कि आप भिक्षुओं के बारे में सब कुछ नहीं छू रहे हैं जो कि sth द्वारा थोड़ा और ऊपर समझाया गया है।
जिमी हॉफ

@ जिमी हॉफ - कोई शक नहीं आप सही हैं। मुझे लगता है कि वास्तव में उन्हें गहराई से समझने के लिए, सबसे अच्छा तरीका यह है कि उन्हें बहुत अधिक उपयोग करना शुरू करें और अनुभव प्राप्त करें । मुझे अभी तक वह अवसर नहीं मिला है, लेकिन मुझे जल्द ही उम्मीद है।
चार्ली फूल

ऐसा लगता है कि प्रोग्रामिंग के संदर्भ में मोनड अमूर्तता का एक उच्च स्तर है, या यह गणित में सिर्फ एक निरंतर और गैर-भिन्न फ़ंक्शन परिभाषा है। किसी भी तरह से, वे नई अवधारणा नहीं हैं, खासकर गणित में।
लियांग

11

एक मोनाड अनिवार्य रूप से प्रसंस्करण स्थगित है। यदि आप ऐसी कोड लिखने की कोशिश कर रहे हैं जिसके साइड इफेक्ट्स हैं (जैसे I / O) ऐसी भाषा में जो उन्हें अनुमति नहीं देती है, और केवल शुद्ध संगणना की अनुमति देती है, तो कहने के लिए एक चकमा है, "ठीक है, मुझे पता है कि आप साइड इफेक्ट नहीं करेंगे मेरे लिए, लेकिन क्या आप गणना कर सकते हैं कि अगर आपने किया तो क्या होगा? "

यह धोखा देने जैसा है।

अब, यह व्याख्या आपको मोनाड्स के बड़े चित्र इरादे को समझने में मदद करेगी, लेकिन शैतान विवरण में है। आप परिणामों की गणना कैसे करते हैं? कभी-कभी, यह सुंदर नहीं है।

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


1
जैसे I रोबोट की किताब? जहां वैज्ञानिक एक कंप्यूटर से अंतरिक्ष यात्रा की गणना करने और कुछ नियमों को छोड़ने के लिए कहते हैं? :) :) :) :)
ऑस्कर रेज़

3
हम्म, ए मोनाड का उपयोग आस्थगित प्रसंस्करण के लिए किया जा सकता है और साइड इफेक्टिंग फ़ंक्शन को एनकैप्सुलेट करने के लिए किया जा सकता है, वास्तव में यह हास्केल में पहला वास्तविक अनुप्रयोग था, लेकिन यह वास्तव में कहीं अधिक सामान्य पैटर्न है। अन्य सामान्य उपयोगों में त्रुटि हैंडलिंग और राज्य प्रबंधन शामिल हैं। सिंटैक्टिक शुगर (हास्केल में करें, एफ # में कम्प्यूटेशन एक्सप्रेशंस, सी # में लाइनक सिंटैक्स) केवल यही है और मोनड्स के लिए मौलिक है।
माइक हैडलो

@MikeHadlow: त्रुटि हैंडलिंग (के लिए इकाई उदाहरणों Maybeऔर Either e) और राज्य प्रबंधन ( State s, ST s) मेरे "कृपया गणना करता है, तो आप [मेरे लिए साइड इफेक्ट] किया था क्या होगा" विशेष उदाहरण के रूप में हड़ताल। एक अन्य उदाहरण नोंडेटेर्मिनिज़्म ( []) होगा।
पियोन

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

लेकिन एक प्रोग्रामर के लिए इसका मतलब है कि हम अपनी शुद्ध भाषा की शुद्ध गणना के साथ मिश्रण करते हुए ईडीएसएल में प्रोग्राम कर सकते हैं। मल्टीलेयर्ड सैंडविच का ढेर एक मल्टीलेयर्ड सैंडविच है। यह इतना आसान है।
विल नेस

4

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


1
जो मुझे और भी अधिक उपयोगी लगा वह टिप्पणी थी जिसमें वीडियो के नीचे C # उदाहरण था।
जलफ

मैं और अधिक उपयोगी के बारे में पता नहीं है , लेकिन यह निश्चित रूप से विचारों को व्यवहार में लाया।
TheMissingLINQ

0

आप एक मठ को C # केinterface रूप में सोच सकते हैं जिसे कक्षाओं को लागू करना होगा । यह एक व्यावहारिक जवाब है कि आप अपने इंटरफेस में इन घोषणाओं को क्यों चुनना चाहते हैं, इसके पीछे सभी श्रेणी के सैद्धांतिक गणित को अनदेखा करते हैं और उन सभी कारणों की अनदेखी करते हैं जो आप एक भाषा में मोनाड्स चाहते हैं जो दुष्प्रभावों से बचने की कोशिश करता है, लेकिन मैंने इसे एक अच्छी शुरुआत के रूप में पाया जो किसी को समझता है (सी #) इंटरफेस।


क्या आप विस्तार से समझा सकते हैं? यह एक इंटरफ़ेस के बारे में क्या है जो इसे मठों से संबंधित करता है?
जोएल कोएहॉर्न

2
मुझे लगता है कि ब्लॉग पोस्ट में उस प्रश्न के लिए समर्पित कई पैराग्राफ हैं।
हाओ

0

मेरी देखें जवाब करने के लिए "क्या एक इकाई है?"

यह एक प्रेरक उदाहरण से शुरू होता है, उदाहरण के माध्यम से काम करता है, एक मोनड का उदाहरण देता है, और औपचारिक रूप से "मोनड" को परिभाषित करता है।

यह कार्यात्मक प्रोग्रामिंग का कोई ज्ञान नहीं मानता है और यह function(argument) := expressionसरलतम संभव अभिव्यक्तियों के साथ वाक्यविन्यास के साथ छद्मकोड का उपयोग करता है ।

यह C # प्रोग्राम स्यूडोडकोड मोनड का कार्यान्वयन है। (संदर्भ के लिए: Mटाइप कंस्ट्रक्टर feedहै, "बाइंड" ऑपरेशन है, और wrap"रिटर्न" ऑपरेशन है।)

using System.IO;
using System;

class Program
{
    public class M<A>
    {
        public A val;
        public string messages;
    }

    public static M<B> feed<A, B>(Func<A, M<B>> f, M<A> x)
    {
        M<B> m = f(x.val);
        m.messages = x.messages + m.messages;
        return m;
    }

    public static M<A> wrap<A>(A x)
    {
        M<A> m = new M<A>();
        m.val = x;
        m.messages = "";
        return m;
    }

    public class T {};
    public class U {};
    public class V {};

    public static M<U> g(V x)
    {
        M<U> m = new M<U>();
        m.messages = "called g.\n";
        return m;
    }

    public static M<T> f(U x)
    {
        M<T> m = new M<T>();
        m.messages = "called f.\n";
        return m;
    }

    static void Main()
    {
        V x = new V();
        M<T> m = feed<U, T>(f, feed(g, wrap<V>(x)));
        Console.Write(m.messages);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.