फ्री मोनाड और रिएक्टिव एक्सटेंशन कैसे सहसंबद्ध है?


14

मैं एक C # बैकग्राउंड से आता हूं, जहां LINQ Rx.NET में विकसित हुआ, लेकिन हमेशा FP में कुछ रुचि थी। मोनाड्स के कुछ परिचय और एफ # में कुछ साइड-प्रोजेक्ट्स के बाद, मैं कोशिश करने और अगले स्तर पर कदम रखने के लिए तैयार था।

अब, स्काला के लोगों से मुक्त मोनाड, और हास्केल में कई राइटअप, या एफ # पर कई वार्ताओं के बाद, मैंने व्याख्याकारों के साथ व्याकरण पाया है, जो समझ में आने के लिए IObservableश्रृंखलाओं के समान हैं।

FRP में आप साइड-इफ़ेक्ट्स और फेल्योर सहित छोटे डोमेन स्पेसिफिक चंक्स से एक ऑपरेशन डेफिनिशन की रचना करते हैं, जो चेन के अंदर रहते हैं, और आपके एप्लिकेशन को ऑपरेशंस और साइड इफेक्ट्स के सेट के रूप में मॉडल करते हैं। नि: शुल्क मोनाड में, अगर मुझे सही ढंग से समझ में आया, तो आप अपने कार्यों को फंक्शनलर्स के रूप में करते हैं, और उन्हें कोयोनेडा का उपयोग करके उठाते हैं।

दोनों के बीच क्या अंतर होगा जो सुई को किसी भी दृष्टिकोण की ओर झुकाता है? आपकी सेवा या कार्यक्रम को परिभाषित करते समय मूलभूत अंतर क्या है?


2
यहां समस्या के बारे में सोचने का एक दिलचस्प तरीका है ... एफआरपी को एक मोनाड के रूप में देखा जा सकता है, भले ही यह आमतौर पर उस तरह से तैयार न हो । अधिकांश (हालांकि सभी नहीं) मोनाड्स मुक्त मोनाड के लिए आइसोमोर्फिक हैं । जैसा कि Contमैंने देखा है कि केवल एक ही मोनाड है जिसे मुक्त मोनाद के माध्यम से व्यक्त नहीं किया जा सकता है, कोई संभवतः मान सकता है कि एफआरपी हो सकता है। जैसा कि लगभग कुछ भी हो सकता है
जूल्स

2
LINQ और Rx.NET दोनों के डिजाइनर एरिक मीजर के अनुसार, IObservableनिरंतरता का एक उदाहरण है।
जोर्ग डब्ल्यू मित्तग

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

जवाबों:


6

monads

एक भिक्षु के होते हैं

  • एक एंडोफूनर । हमारे सॉफ्टवेयर इंजीनियरिंग की दुनिया में, हम कह सकते हैं कि यह एक एकल, अप्रतिबंधित प्रकार के पैरामीटर के साथ डेटाटाइप से मेल खाती है। C # में, यह फ़ॉर्म का कुछ होगा:

    class M<T> { ... }
    
  • उस डेटाटाइप पर परिभाषित दो ऑपरेशन:

    • return/ pureएक "शुद्ध" मान (यानी, एक Tमान) लेता है और इसे मोनाड में लपेटता है (यानी, यह एक M<T>मूल्य पैदा करता है )। चूंकि returnC # में एक आरक्षित कीवर्ड है, मैं pureअब से इस ऑपरेशन को संदर्भित करने के लिए उपयोग करूंगा । C # में, pureहस्ताक्षर के साथ एक विधि होगी:

      M<T> pure(T v);
      
    • bind/ flatmapएक मानद मूल्य ( M<A>) और एक फ़ंक्शन लेता है ffएक शुद्ध मूल्य लेता है और एक मुद्रीकृत मूल्य ( M<B>) लौटाता है । इनसे, bindएक नया मानद मूल्य ( M<B>) पैदा करता है । bindनिम्नलिखित C # हस्ताक्षर है:

      M<B> bind(M<A> mv, Func<A, M<B>> f);
      

इसके अलावा, एक मोनाड होने के लिए, pureऔर bindतीन मोनाद कानूनों का पालन करना आवश्यक है।

अब, C # में एक मॉडल बनाने का एक तरीका इंटरफ़ेस का निर्माण करना होगा:

interface Monad<M> {
  M<T> pure(T v);
  M<B> bind(M<A> mv, Func<A, M<B>> f);
}

(नोट: चीजों को संक्षिप्त और अभिव्यंजक रखने के लिए, मैं इस उत्तर के दौरान कोड के साथ कुछ स्वतंत्रता ले जाऊंगा।)

अब हम ठोस डेटाटाइप्स के लिए मोनोएड को लागू कर सकते हैं Monad<M>। उदाहरण के लिए, हम निम्नलिखित के लिए निम्नलिखित को लागू कर सकते हैं IEnumerable:

class IEnumerableM implements Monad<IEnumerable> {
  IEnumerable<T> pure(T v) {
    return (new List<T>(){v}).AsReadOnly();
  }

  IEnumerable<B> bind(IEnumerable<A> mv, Func<A, IEnumerable<B>> f) {
    ;; equivalent to mv.SelectMany(f)
    return (from a in mv
            from b in f(a)
            select b);
  }
}

(मैं LINQ सिंटैक्स और मोनडेस के बीच संबंध को कॉल करने के लिए LINQ सिंटैक्स का उपयोग करता हूं। लेकिन ध्यान दें कि हम LINQ क्वेरी को कॉल के साथ बदल सकते हैं SelectMany।)

अब, क्या हम एक सन्यासी को परिभाषित कर सकते हैं IObservable? ऐसा लगता है:

class IObservableM implements Monad<IObservable> {
  IObservable<T> pure(T v){
    Observable.Return(v);
  }

  IObservable<B> bind(IObservable<A> mv, Func<A, IObservable<B>> f){
    mv.SelectMany(f);
  }
}

यह सुनिश्चित करने के लिए कि हमारे पास एक मोनाड है, हमें मोनाद कानूनों को साबित करने की आवश्यकता है। यह गैर-तुच्छ हो सकता है (और मैं Rx.NET के साथ पर्याप्त रूप से परिचित नहीं हूं यह जानने के लिए कि क्या उन्हें अकेले विनिर्देश से भी साबित किया जा सकता है), लेकिन यह एक आशाजनक शुरुआत है। इस चर्चा के शेष भाग को सुविधाजनक बनाने के लिए, आइए मान लेते हैं कि इस मामले में मोनाड कानूनों की पकड़ है।

नि: शुल्क मोनाडेस

कोई विलक्षण "मुक्त मोनाड" नहीं है। बल्कि, मुफ्त मोनाड एक वर्ग के भिक्षु हैं जो कि फंक्शनलर्स से निर्मित होते हैं। यही कारण है कि, एक फ़नकार दिया जाता है F, हम स्वचालित रूप से F(यानी, मुक्त मोनाद F) के लिए एक मोदक प्राप्त कर सकते हैं ।

functors

मोनाड्स की तरह, फंक्शनलर्स को निम्नलिखित तीन वस्तुओं द्वारा परिभाषित किया जा सकता है:

  • एक डेटाटाइप, एक एकल, अप्रतिबंधित प्रकार चर पर पैरामीटरित।
  • दो ऑपरेशन:

    • pureफ़्यूचर में एक शुद्ध मूल्य लपेटता है। यह pureएक सन्यासी के लिए अनुरूप है । वास्तव में, फंक्शनलर्स के लिए जो एक मोनड भी हैं, दोनों समान होने चाहिए।
    • fmapकिसी दिए गए फ़ंक्शन के माध्यम से आउटपुट में नए मूल्यों के लिए मानचित्र मान। यह हस्ताक्षर है:

      F<B> fmap(Func<A, B> f, F<A> fv)
      

मठों की तरह, फंक्शंस कानूनों का पालन करने के लिए फंक्शनलर्स की आवश्यकता होती है।

मोनाड्स के समान, हम निम्नलिखित इंटरफ़ेस के माध्यम से फंक्शनल मॉडल कर सकते हैं:

interface Functor<F> {
  F<T> pure(T v);
  F<B> fmap(Func<A, B> f, F<A> fv);
}

अब, चूँकि मोनाड फंक्शंस के उप-वर्ग हैं, इसलिए हम Monadथोड़ा भी रिफ्लेक्टर कर सकते हैं :

interface Monad<M> extends Functor<M> {
  M<T> join(M<M<T>> mmv) {
    Func<T, T> identity = (x => x);
    return mmv.bind(x => x); // identity function
  }

  M<B> bind(M<A> mv, Func<A, M<B>> f) {
    join(fmap(f, mv));
  }
}

यहां मैंने एक अतिरिक्त विधि जोड़ी है join, और दोनों का डिफ़ॉल्ट कार्यान्वयन प्रदान किया है joinऔर bind। ध्यान दें, हालांकि, ये परिपत्र परिभाषाएं हैं। इसलिए आपको कम से कम एक या दूसरे को ओवरराइड करना होगा। इसके अलावा, ध्यान दें कि pureअब से विरासत में मिला है Functor

IObservable और मुफ्त मोनाड्स

अब, क्योंकि हमने एक सन्यासी को परिभाषित किया है IObservableऔर चूँकि भिक्षुओं के उप-वर्ग हैं, तो यह इस प्रकार है कि हमें एक फ़नकार के उदाहरण को परिभाषित करने में सक्षम होना चाहिए IObservable। यहाँ एक परिभाषा है:

class IObservableF implements Functor<IObservable> {
  IObservable<T> pure(T v) {
    return Observable.Return(v);
  }

  IObservable<B> fmap(Func<A, B> f, IObservable<A> fv){
    return fv.Select(f);
  }
}

अब जब हमारे पास एक फ़ंक्टर है जिसे IObservableहम परिभाषित कर सकते हैं, हम उस फ़नकार से एक मुफ्त मोनाड का निर्माण कर सकते हैं। और यह ठीक है कि कैसे IObservableमुक्त भिक्षुओं से संबंधित है - अर्थात्, हम से एक मुक्त मठ का निर्माण कर सकते हैं IObservable


श्रेणी सिद्धांत की व्यावहारिक समझ! मैं कुछ ऐसा था, जिसके बारे में बात नहीं की गई कि वे कैसे बनाए जाते हैं, अंतर के बारे में और जब दोनों के साथ एक कार्यात्मक वास्तुकला और मॉडलिंग प्रभाव रचना का निर्माण होता है। FreeMonad का उपयोग रीफाइंड ऑपरेशंस के लिए DSLs के निर्माण के लिए किया जा सकता है, जबकि IObservables समय के साथ असतत मूल्यों के बारे में अधिक हैं।
MLProgrammer-CiM

1
@ MLProgrammer-CiM, मैं देखूंगा कि क्या मैं अगले कुछ दिनों में उस पर कुछ अंतर्दृष्टि जोड़ सकता हूं।
नाथन डेविस

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