Monads
একজন একসংখ্যা নিয়ে গঠিত
একটি এন্ডোফান্টর । আমাদের সফ্টওয়্যার ইঞ্জিনিয়ারিং জগতে, আমরা এটি বলতে পারি এটি একটি একক, সীমাহীন টাইপের প্যারামিটারের সাথে ডেটাটাইপের সাথে সঙ্গতিপূর্ণ। সি # তে এটি রূপের কিছু হবে:
class M<T> { ... }
সেই ডেটাটাইপের উপরে দুটি ক্রিয়াকলাপ সংজ্ঞায়িত:
return
/ pure
একটি "খাঁটি" মান (অর্থাত্, একটি T
মান) নেয় এবং এটি মোনাদে "মোড়ানো" (অর্থাত, এটি একটি M<T>
মান দেয়)। যেহেতু return
সি # তে একটি সংরক্ষিত কীওয়ার্ড, তাই আমি pure
এখন থেকে এই ক্রিয়াকলাপটি উল্লেখ করতে ব্যবহার করব । সি # তে, pure
স্বাক্ষরযুক্ত এমন একটি পদ্ধতি হবে:
M<T> pure(T v);
bind
/ flatmap
একটি monadic মান ( M<A>
) এবং একটি ফাংশন লাগে f
। f
একটি খাঁটি মান নেয় এবং একটি একক মান ( M<B>
) প্রদান করে। এগুলি থেকে, bind
একটি নতুন monadic মান ( M<B>
) উত্পাদন করে । bind
নিম্নলিখিত সি # স্বাক্ষর রয়েছে:
M<B> bind(M<A> mv, Func<A, M<B>> f);
এছাড়াও, একটি মোনাদ হতে, pure
এবং bind
তিনটি মোনাড আইন মান্য করা আবশ্যক।
এখন, সি # তে মোডের মডেল করার একটি উপায় হ'ল একটি ইন্টারফেস তৈরি করা:
interface Monad<M> {
M<T> pure(T v);
M<B> bind(M<A> mv, Func<A, M<B>> f);
}
(দ্রষ্টব্য: বিষয়গুলি সংক্ষিপ্ত এবং অভিব্যক্তিপূর্ণ রাখার জন্য, আমি এই উত্তর জুড়ে কোডটি দিয়ে কিছু স্বাধীনতা গ্রহণ করব be)
এখন আমরা কংক্রিটের বাস্তবায়নের মাধ্যমে কংক্রিটের ডেটাজিপগুলির জন্য মনডগুলি প্রয়োগ করতে পারি Monad<M>
। উদাহরণস্বরূপ, আমরা নিম্নলিখিত monad এর জন্য প্রয়োগ করতে পারি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);
}
}
(আমি লিনকিউ সিনট্যাক্স এবং মোনাডের মধ্যে সম্পর্কটি কল করার জন্য আমি লিনকিউ সিনট্যাক্সটি ব্যবহার করছি But তবে নোট করুন আমরা একটি কল দিয়ে লিনকিউ কোয়েরিটি প্রতিস্থাপন করতে পারি SelectMany
))
এখন, আমরা একটি monad সংজ্ঞায়িত করতে পারি 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
, আমরা স্বয়ংক্রিয়ভাবে জন্য একটি monad প্রাপ্ত করতে পারেনF
(যেমন, মুক্ত মনাদ F
) এর ।
Functors
স্নাদের মতো, ফান্টেক্টরগুলি নিম্নলিখিত তিনটি আইটেম দ্বারা সংজ্ঞায়িত করা যেতে পারে:
- একটি ডেটাটাইপ, একটি একক, সীমাহীন টাইপের ভেরিয়েবলের উপরে প্যারামিটারাইজড।
দুটি অপারেশন:
pure
ফান্টারে একটি খাঁটি মান psেকে দেয়। এটি 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
এবং বিনামূল্যে Monads
এখন, যেহেতু আমরা একটি মোনাডকে সংজ্ঞায়িত করেছি 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
।
Cont
শুধুমাত্র এক সম্ভবত অনুমান করতে পারেন এফআরপি হতে পারে আমি দেখেছি যে বিনামূল্যে একসংখ্যা মাধ্যমে প্রকাশ করা যাবে না একসংখ্যা হয়। প্রায় অন্য কিছু হিসাবে ।