সরল ইংলিশে মোনাদ? (কোনও এফপি ব্যাকগ্রাউন্ড ছাড়াই ওওপি প্রোগ্রামারটির জন্য)


743

কোনও ওওপি প্রোগ্রামার বুঝতে পারে (কোনও কার্যকরী প্রোগ্রামিং ব্যাকগ্রাউন্ড ছাড়াই), মোনাদ কী?

এটি কোন সমস্যার সমাধান করে এবং এটি ব্যবহৃত সবচেয়ে সাধারণ জায়গা কোনটি?

সম্পাদনা করুন:

আমি যে ধরণের বোঝার সন্ধান করছিলাম তা স্পষ্ট করার জন্য, আসুন আমরা বলি যে আপনি কোনও এফপি অ্যাপ্লিকেশনটি রূপান্তর করেছিলেন যা সোনাদিকে একটি ওওপি প্রয়োগে রূপান্তর করেছিল into আপনি ওওপি অ্যাপ্লিকেশনটিতে মনদাদের দায়িত্বগুলি পোর্ট করতে কী করবেন?


10


10
@ পাভেল: এরিকের কাছ থেকে আমরা যে উত্তরটি পেয়েছি তা ওও ব্যাকগ্রাউন্ডযুক্ত ব্যক্তির জন্য (এফপি ব্যাকগ্রাউন্ডের বিপরীতে) অন্য প্রস্তাবিত প্রশ্নাবলীর চেয়ে যে উত্তরটি পেয়েছে তার চেয়ে অনেক ভাল।
ডোনাল ফেলো

5
@ ডোনাল: যদি এটি একটি ডুপ হয় (যার সম্পর্কে আমার কোনও মতামত নেই), ভাল উত্তরটি মূলটিতে যুক্ত করা উচিত। এটি: একটি ভাল উত্তর সদৃশ হিসাবে বন্ধ করা থামায় না। এটি যদি যথেষ্ট পরিমাণে সদৃশ হয় তবে এটি কোনও সংযোজন হিসাবে কোনও মডারেটর দ্বারা সম্পাদন করা যেতে পারে।
dmckee --- প্রাক্তন মডারেটর বিড়ালছানা

উত্তর:


732

আপডেট: এই প্রশ্নটি ছিল একটি দীর্ঘ দীর্ঘ ব্লগ সিরিজের বিষয়, যা আপনি মোনাদসে পড়তে পারেন - দুর্দান্ত প্রশ্নের জন্য ধন্যবাদ!

কোনও ওওপি প্রোগ্রামার বুঝতে পারে (কোনও কার্যকরী প্রোগ্রামিং ব্যাকগ্রাউন্ড ছাড়াই), মোনাদ কী?

একজন একসংখ্যা একটি হল ধরনগুলোর মধ্যে "পরিবর্ধক" যে নির্দিষ্ট নিয়ম মেনে চলে এবং যা প্রদান করা নির্দিষ্ট অপারেশন হয়েছে

প্রথমত, "প্রকারের পরিবর্ধক" কী? এর অর্থ আমার এমন কিছু সিস্টেম যা আপনাকে একটি ধরণের নিতে এবং এটিকে আরও বিশেষ ধরণের রূপান্তর করতে দেয়। উদাহরণস্বরূপ, সি # তে বিবেচনা করুন Nullable<T>। এটি প্রকারের একটি পরিবর্ধক। এটি আপনাকে একটি টাইপ নিতে, বলতে intএবং সেই ধরণের একটি নতুন সক্ষমতা যোগ করতে দেয়, যথা, এটি এখন আগে নষ্ট হওয়ার পরে শূন্য হতে পারে।

দ্বিতীয় উদাহরণ হিসাবে বিবেচনা করুন IEnumerable<T>। এটি প্রকারের একটি পরিবর্ধক। এটি আপনাকে একটি টাইপ নিতে, বলতে, stringএবং সেই ধরণের একটি নতুন ক্ষমতা যুক্ত করতে দেয়, যথা, আপনি এখন যে কোনও সংখ্যক একক স্ট্রিংয়ের মধ্যে স্ট্রিংগুলির ক্রম তৈরি করতে পারেন।

"নির্দিষ্ট বিধি" কি কি? সংক্ষেপে, যে অন্তর্নিহিত ধরণের ফাংশনগুলির প্রশস্ত প্রকারে কাজ করার জন্য একটি বুদ্ধিমান উপায় রয়েছে যেগুলি কার্যকরী রচনার সাধারণ নিয়মগুলি অনুসরণ করে। উদাহরণস্বরূপ, আপনার যদি পূর্ণসংখ্যার উপর কোনও ফাংশন থাকে, বলুন

int M(int x) { return x + N(x * 2); }

তারপরে সংশ্লিষ্ট ফাংশনটি Nullable<int>সমস্ত অপারেটর এবং কলগুলিকে সেখানে আগের মতো "একইভাবে" একসাথে কাজ করতে পারে।

(এটি অবিশ্বাস্যরূপে অস্পষ্ট এবং অনর্থক; আপনি এমন ব্যাখ্যা চেয়েছিলেন যা কার্যকরী রচনার জ্ঞান সম্পর্কে কিছুই ধরে নেয়নি।)

"অপারেশন" কি?

  1. একটি "ইউনিট" অপারেশন রয়েছে (বিভ্রান্তিমূলকভাবে কখনও কখনও "রিটার্ন" অপারেশন বলা হয়) যা একটি সরল ধরণের থেকে একটি মান নেয় এবং সমতুল্য মনডিক মান তৈরি করে। এটি, সংক্ষেপে, একটি অবিশ্রুত প্রকারের মান গ্রহণ এবং এম্প্লিফাইড টাইপের মানকে রূপান্তর করার একটি উপায় সরবরাহ করে। এটি কোনও ওও ভাষায় নির্মাতা হিসাবে প্রয়োগ করা যেতে পারে।

  2. একটি "বাইন্ড" অপারেশন রয়েছে যা একটি monadic মান এবং একটি ফাংশন নেয় যা মানটিকে রূপান্তর করতে পারে এবং একটি নতুন monadic মান প্রদান করে। বাইন্ড হ'ল মূল অপারেশন যা মোনাডের শব্দার্থবিজ্ঞানকে সংজ্ঞায়িত করে। এটি আমাদের বর্ণহীন প্রকারের ক্রিয়াকলাপকে পরিবর্ধিত প্রকারের ক্রিয়াকলাপগুলিতে রূপান্তর করতে দেয় যা পূর্বে উল্লিখিত কার্যকরী রচনার নিয়মগুলি মানায়।

  3. এমপ্ল্লিফাইড টাইপটি এমপ্লিফাইড টাইপ থেকে ফিরে পাওয়ার প্রায়শই একটি উপায় রয়েছে। এই অপারেশনটি কঠোরভাবে বলতে গেলে একটি মনাড থাকা প্রয়োজন। (যদিও আপনি কমোনাড রাখতে চান এটি প্রয়োজনীয় । আমরা এই নিবন্ধে আরও বিবেচনা করব না))

আবার, Nullable<T>উদাহরণ হিসাবে নেওয়া । আপনি কনস্ট্রাক্টরের সাহায্যে একটিতে intরূপান্তর করতে পারেন Nullable<int>। সি # সংকলক আপনার জন্য সবচেয়ে নিকৃষ্ট "উত্তোলন" র যত্ন করে তবে এটি যদি না ঘটে তবে উত্তোলনের রূপান্তরটি সোজা: একটি অপারেশন, বলুন,

int M(int x) { whatever }

রূপান্তরিত হয়

Nullable<int> M(Nullable<int> x) 
{ 
    if (x == null) 
        return null; 
    else 
        return new Nullable<int>(whatever);
}

এবং একটি Nullable<int>ফিরে পরিণত সম্পত্তি intসঙ্গে সম্পন্ন হয় Value

এটি ফাংশন রূপান্তর যে মূল বিট। লক্ষ্য করুন যে কীভাবে নলযোগ্য অপারেশনটির প্রকৃত শব্দার্থক শব্দ - যে কোনও অপারেশন nullপ্রচার করে null- রূপান্তরিত হয়। আমরা এটিকে সাধারণীকরণ করতে পারি।

ধরুন আপনার কাছ থেকে একটি ফাংশন আছে intকরার int, আমাদের মূল মত M। আপনি এটি সহজেই কোনও ফাংশনে পরিণত করতে পারেন যা গ্রহণ করে intএবং Nullable<int>এটির কারণ আপনি কেবলমাত্র নালাযুক্ত নির্মাণকারীর মাধ্যমে ফলাফল চালাতে পারেন। এখন ধরুন আপনার কাছে এই উচ্চ-অর্ডার পদ্ধতি রয়েছে:

static Nullable<T> Bind<T>(Nullable<T> amplified, Func<T, Nullable<T>> func)
{
    if (amplified == null) 
        return null;
    else
        return func(amplified.Value);
}

আপনি এটি দিয়ে কি করতে পারেন দেখুন? যে কোনও পদ্ধতি গ্রহণ করে intএবং একটি ফেরত দেয় int, বা গ্রহণ করে intএবং ফেরত দেয় এমন কোনও পদ্ধতিতে Nullable<int>এখন এটি নলযোগ্য শব্দার্থতাকে প্রয়োগ করতে পারে

আরও: ধরুন আপনার দুটি পদ্ধতি রয়েছে

Nullable<int> X(int q) { ... }
Nullable<int> Y(int r) { ... }

এবং আপনি তাদের রচনা করতে চান:

Nullable<int> Z(int s) { return X(Y(s)); }

অর্থাৎ Zরচনা হয় Xএবং Y। কিন্তু আপনি এটি করতে পারবেন না কারণ এটি Xগ্রহণ করে intএবং Yফিরে আসে Nullable<int>। তবে আপনার "বাইন্ড" অপারেশন হওয়ায় আপনি এই কাজটি করতে পারেন:

Nullable<int> Z(int s) { return Bind(Y(s), X); }

একটি মোনাডে বাইন্ড অপারেশন হ'ল প্রসারিত ধরণের কাজগুলিতে ফাংশনগুলির সংমিশ্রণ তৈরি করে। উপরে যে "বিধিগুলি" আমি হাতছাড়া করেছি তা হ'ল মোনাদ সাধারণ ফাংশন রচনার নিয়মগুলি সংরক্ষণ করে; যে পরিচয় ফাংশনগুলির সাথে রচনাটি মূল ফাংশনটির ফলাফল দেয়, সেই সংমিশ্রণটি সাহসী এবং আরও কিছু।

সি # তে "বাইন্ড" কে "সিলেক্টম্যানি" বলা হয়। এটি সিকোয়েন্স মোনাডে কীভাবে কাজ করে তা একবার দেখুন। আমাদের দুটি জিনিস থাকা দরকার: একটি মানকে সিকোয়েন্সে পরিণত করুন এবং ক্রমানুসারে ক্রিয়াকলাপগুলি আবদ্ধ করুন। বোনাস হিসাবে, আমাদের "একটি সিক্যুয়েন্সকে আবার একটি মানতে পরিণত করা" আছে। এই অপারেশনগুলি হ'ল:

static IEnumerable<T> MakeSequence<T>(T item)
{
    yield return item;
}
// Extract a value
static T First<T>(IEnumerable<T> sequence)
{
    // let's just take the first one
    foreach(T item in sequence) return item; 
    throw new Exception("No first item");
}
// "Bind" is called "SelectMany"
static IEnumerable<T> SelectMany<T>(IEnumerable<T> seq, Func<T, IEnumerable<T>> func)
{
    foreach(T item in seq)
        foreach(T result in func(item))
            yield return result;            
}

অবিচ্ছিন্ন মোনাড নিয়মটি ছিল "দুটি ফাংশনকে একত্রিত করে যা এক সাথে nullable উত্পাদন করে, তা পরীক্ষা করে দেখুন যে অভ্যন্তরীণটি শূন্য হয় কিনা; যদি তা করে, নাল উত্পাদন করে, যদি তা না হয়, তবে ফলাফলের সাথে বাইরেরটিকে কল করুন"। এটি নালার পছন্দসই শব্দার্থক।

সিকোয়েন্স মোনাড নিয়মটি হ'ল "দুটি ক্রিয়াকে একত্রিত করা যা এক সাথে ক্রম উত্পাদন করে, অভ্যন্তরীণ ফাংশন দ্বারা উত্পাদিত প্রতিটি উপাদানগুলিতে বাইরের ফাংশনটি প্রয়োগ করে এবং তারপরে সমস্ত ফলাফলের ক্রমগুলি এক সাথে যুক্ত করে"। স্নাতকের মৌলিক শব্দার্থ Bind/ SelectManyপদ্ধতিতে ধরা পড়ে ; এটিই সেই পদ্ধতি যা আপনাকে জানায় যে মোনাদটির প্রকৃত অর্থ

আমরা আরও ভাল করতে পারি। ধরুন আপনার কাছে কক্ষের ক্রম রয়েছে, এবং এমন একটি পদ্ধতি যা কীট গ্রহণ করে এবং স্ট্রিংয়ের ক্রমগুলিতে ফলাফল দেয়। একের ইনপুটগুলি অন্যটির আউটপুটগুলির সাথে মেলে যতক্ষণ না বিভিন্ন প্রসারিত প্রকার গ্রহণ করে এবং ফেরত দেয় এমন ফাংশনগুলির সংমিশ্রণের জন্য আমরা বাইন্ডিং অপারেশনটিকে সাধারণকরণ করতে পারি:

static IEnumerable<U> SelectMany<T,U>(IEnumerable<T> seq, Func<T, IEnumerable<U>> func)
{
    foreach(T item in seq)
        foreach(U result in func(item))
            yield return result;            
}

সুতরাং এখন আমরা বলতে পারি "পৃথক সংখ্যার এই গুচ্ছটিকে পূর্ণসংখ্যার অনুক্রমের আকারে প্রসারিত করুন this সমস্ত স্ট্রিং ক্রম। " মনডস আপনাকে আপনার প্রশস্তকরণগুলি রচনা করতে দেয় ।

এটি কোন সমস্যার সমাধান করে এবং এটি ব্যবহৃত সবচেয়ে সাধারণ জায়গা কোনটি?

এটি "সিঙ্গলটন প্যাটার্নটি কী সমস্যাগুলি সমাধান করে?" জিজ্ঞাসার মতো, তবে আমি এটিকে একটি শট দেব।

মনডাস সাধারণত সমস্যাগুলি সমাধান করতে ব্যবহৃত হয়:

  • আমার এই ধরণের জন্য নতুন ক্ষমতা তৈরি করতে হবে এবং এখনও নতুন ক্ষমতাগুলি ব্যবহার করতে এই ধরণের পুরানো ফাংশনগুলি একত্রিত করতে হবে।
  • আমাকে প্রকারভেদে প্রচুর অপারেশন ক্যাপচার করতে হবে এবং সেই অপারেশনগুলিকে কমপোজেবল অবজেক্ট হিসাবে উপস্থাপন করতে হবে, যতক্ষণ না আমার সঠিক ক্রমগুলি উপস্থাপন করা হচ্ছে ততক্ষণ বড় এবং বৃহত্তর রচনাগুলি তৈরি করা উচিত এবং তারপরে আমাকে জিনিসটি থেকে ফলাফল বের করা শুরু করতে হবে
  • পার্শ্ব প্রতিক্রিয়া ঘৃণা করে এমন ভাষায় আমার পরিষ্কার-পরিচ্ছন্নতার অপারেশনগুলি উপস্থাপন করতে হবে

সি # এর নকশায় মনড ব্যবহার করে। ইতিমধ্যে উল্লিখিত হিসাবে, নল প্যাটার্ন অত্যন্ত "সম্ভবত মনাদ" এর অনুরূপ। লিনকিউ পুরোপুরি মনড থেকে তৈরি; SelectManyপদ্ধতি অপারেশনের রফা শব্দার্থিক কাজ করে কি। (এরিক মাইজার দেখানোর পক্ষে যে প্রতিটি লিনকিউ ফাংশন আসলে বাস্তবায়িত হতে পারে SelectMany; অন্য সব কিছুই কেবল একটি সুবিধা।

আমি যে ধরণের বোঝার সন্ধান করছিলাম তা স্পষ্ট করার জন্য, আসুন আমরা বলি যে আপনি কোনও এফপি অ্যাপ্লিকেশনটি রূপান্তর করেছিলেন যা সোনাদিকে একটি ওওপি প্রয়োগে রূপান্তর করেছিল into আপনি ওওপি অ্যাপ্লিকেশনটিতে মনদাদের দায়িত্বগুলি পোর্ট করতে কী করবেন?

বেশিরভাগ ওওপি ভাষায় সরাসরি মোনাডের প্যাটার্ন উপস্থাপনের জন্য যথেষ্ট পরিমাণে সমৃদ্ধ সিস্টেম নেই; আপনার একটি টাইপ সিস্টেমের দরকার যা জেনেরিক ধরণের চেয়ে বেশি প্রকারেরগুলিকে সমর্থন করে। সুতরাং আমি এটি করার চেষ্টা করব না। বরং আমি জেনেরিক প্রকারগুলি প্রয়োগ করব যা প্রতিটি মোনাডকে উপস্থাপন করে এবং এমন তিনটি ক্রিয়াকলাপ প্রয়োগ করে যা আপনার প্রয়োজনীয় তিনটি ক্রিয়াকলাপকে উপস্থাপন করে: একটি মানকে প্রশস্ত মান হিসাবে রূপান্তর করা, (সম্ভবত) একটি পরিবর্ধিত মানকে একটি মানকে রূপান্তর করা, এবং অসম্পূর্ণ মানগুলিতে কোনও ক্রিয়াকে রূপান্তরকরণ প্রশস্ত মানগুলির উপর একটি ফাংশন।

শুরু করার জন্য একটি ভাল জায়গা হ'ল আমরা কীভাবে সি # তে লিনিকিউ প্রয়োগ করেছি। SelectManyপদ্ধতিটি অধ্যয়ন করুন ; সিকোয়েন্স মোনাড সি # তে কীভাবে কাজ করে তা বোঝার মূল চাবিকাঠি। এটি একটি খুব সাধারণ পদ্ধতি, তবে খুব শক্তিশালী!


প্রস্তাবিত, আরও পড়া:

  1. সি # তে মনডগুলির আরও গভীরতা এবং তাত্ত্বিকভাবে ব্যাখ্যা করার জন্য, আমি এই বিষয়ে আমার ( এরিক লিপার্টের ) সহকর্মী ওয়েস ডায়েরের নিবন্ধটির জন্য অত্যন্ত পরামর্শ দিচ্ছি । এই নিবন্ধটি হ'ল আমার কাছে মনডদের ব্যাখ্যা করেছেন যখন শেষ পর্যন্ত তারা আমার জন্য "ক্লিক করেছেন"।
  2. আপনি কেন চারপাশে একটি মোনাড চাইতে পারেন তার একটি ভাল চিত্র (এর উদাহরণগুলিতে হাস্কেল ব্যবহার করে)
  3. জাভাস্ক্রিপ্টে পূর্ববর্তী নিবন্ধটির "অনুবাদ" সাজান।


17
এটি দুর্দান্ত উত্তর, তবে আমার মাথাটি ছদ্মবেশী। আমি এই সপ্তাহান্তে অনুসরণ করছি এবং তার দিকে তাকাব এবং যদি জিনিসগুলি স্থির না হয় এবং আমার মাথায় অর্থবোধ না করে তবে আপনাকে প্রশ্ন করব।
পল নাথান

5
যথারীতি এরিকের মতো দুর্দান্ত ব্যাখ্যা। আরও তাত্ত্বিক (তবে এখনও অত্যন্ত আকর্ষণীয়) আলোচনার জন্য আমি বার্ন ডি স্মেটের ব্লগ পোস্টটি মিনলিংকুতে কিছু কার্যকরী প্রোগ্রামিং কনস্ট্রাক্টস সি-তে ফিরে আসতে সহায়ক বলে খুঁজে পেয়েছি। সম্প্রদায়.বার্টডেসমেট.এন.এল.ব্লগস
বার্ট / অর্চিভ/২০১০/01/01/…

41
এটা বলার আমার আরো ইন্দ্রিয় তোলে augments বদলে ধরনের শক্তি যোগায় তাদের।
গাবে

61
@ স্লোমোজো: এবং আমি যা লিখেছিলাম এবং কী লিখতে চেয়েছি তা এটিকে আবার পরিবর্তন করেছি। আপনি এবং গাবে যদি নিজের উত্তর লিখতে চান তবে আপনি ঠিক এগিয়ে যান।
এরিক লিপার্ট

24
@ এরিক, অবশ্যই আপনার উপরে, তবে পরিবর্ধক দ্বারা বোঝা যাচ্ছে যে বিদ্যমান বৈশিষ্ট্যগুলি উত্সাহিত, যা বিভ্রান্তিকর।
অক্টোডো

341

আমাদের কেন সোনার দরকার?

  1. আমরা কেবল ফাংশন ব্যবহার করে প্রোগ্রাম করতে চাই । (সমস্ত-এফপি পরে "ফাংশনাল প্রোগ্রামিং")।
  2. তারপরে, আমাদের প্রথম বড় সমস্যা রয়েছে। এটি একটি প্রোগ্রাম:

    f(x) = 2 * x

    g(x,y) = x / y

    প্রথমে মৃত্যুদন্ড কার্যকর করার বিষয়টি কীভাবে আমরা বলতে পারি ? কীভাবে আমরা ফাংশনগুলির চেয়ে বেশি ব্যবহার না করে ফাংশনগুলির (যেমন একটি প্রোগ্রাম ) একটি আদেশযুক্ত ক্রম গঠন করতে পারি ?

    সমাধান: রচনা ফাংশন । আপনি যদি প্রথমে চান gএবং তারপর f, শুধু লিখুন f(g(x,y))। ঠিক আছে কিন্তু ...

  3. আরও সমস্যা: কিছু ফাংশন ব্যর্থ হতে পারে (যেমন g(2,0), 0 দ্বারা ভাগ)। আমরা আশা করি আপনি না "ব্যতিক্রম" FP মধ্যে । আমরা কীভাবে এটি সমাধান করব?

    সমাধান: আসুন ফাংশনগুলিকে দুটি ধরণের জিনিস ফিরে আসার অনুমতি দিন: g : Real,Real -> Realদুটি ক্ষেত্র থেকে দুটি বাস্তবের মধ্যে ফাংশন রাখার পরিবর্তে আসুন g : Real,Real -> Real | Nothing(দুটি রিয়েল থেকে ফাংশনকে (আসল বা কিছুই নয়)) অনুমতি দিন।

  4. তবে ফাংশনগুলি (সহজ হতে) কেবল একটি জিনিস ফেরত দেওয়া উচিত ।

    সমাধান: আসুন ফেরত দেওয়ার জন্য একটি নতুন ধরণের ডেটা তৈরি করুন, একটি " বক্সিং টাইপ " যা সম্ভবত একটি বাস্তবকে আবদ্ধ করে দেয় বা কেবল কিছুই নয়। সুতরাং, আমরা থাকতে পারে g : Real,Real -> Maybe Real। ঠিক আছে কিন্তু ...

  5. এখন কি হবে f(g(x,y))? fএকটি গ্রাস করতে প্রস্তুত নয় Maybe Real। এবং, আমরা প্রতি ফাংশন আমরা এর সাথে যুক্ত হতে পারে পরিবর্তন করতে চাই না gএকটি গ্রাস Maybe Real

    সমাধান: আসুন "সংযুক্ত" / "রচনা" / "লিঙ্ক" ফাংশনগুলির জন্য একটি বিশেষ ক্রিয়া করি । এইভাবে, আমরা, পর্দার আড়ালে, একটি ফাংশনের আউটপুট নীচেরটিকে খাওয়ানোর জন্য অভিযোজিত করতে পারি।

    আমাদের ক্ষেত্রে ইন: g >>= f(কানেক্ট / রচনা gকরতে f)। আমরা আউটপুট >>=পেতে চাই g, এটি পরিদর্শন করতে চাই এবং যদি এটি Nothingকেবল কল না করে fফিরে আসে Nothing; বা বিপরীতে, বাক্সটি বের করুন Realএবং fএটি দিয়ে ফিড দিন। (এই অ্যালগরিদম কেবল প্রকারের >>=জন্য বাস্তবায়ন Maybe)।

  6. অন্যান্য অনেক সমস্যা দেখা দেয় যা একই প্যাটার্নটি ব্যবহার করে সমাধান করা যেতে পারে: ১. বিভিন্ন অর্থ / মানকে কোডিফ / সংরক্ষণ করতে একটি "বাক্স" ব্যবহার করুন এবং gসেই "বাক্সযুক্ত মানগুলি" ফিরিয়ে দেওয়ার মতো ফাংশন রাখুন । ২. এর আউটপুটটির ইনপুটটিতে g >>= fসংযোগ স্থাপনে সহায়তা করার জন্য সুরকার / লিকার আছে , সুতরাং আমাদের কোনও পরিবর্তন করতে হবে না।gff

  7. এই কৌশলটি ব্যবহার করে সমাধানযোগ্য সমস্যাগুলি হ'ল:

    • একটি বিশ্বব্যাপী অবস্থা রয়েছে যে ক্রমানুসারে প্রতিটি ক্রিয়াকলাপ ("প্রোগ্রাম") ভাগ করতে পারে: সমাধান StateMonad

    • আমরা "অপরিষ্কার ফাংশন" পছন্দ করি না: ফাংশনগুলি যা একই ইনপুটটির জন্য আলাদা আউটপুট দেয় । সুতরাং, আসুন সেই ফাংশনগুলি চিহ্নিত করুন, যাতে তারা ট্যাগ / বাক্সযুক্ত মানটি ফিরিয়ে দেয়: মোনাড।IO

মোট সুখ !!!!


2
@ দিমিত্রিজেটসেভ ব্যতিক্রমগুলি কেবল "অপরিষ্কার কোড" (আইও মোনাড) এ ঘটতে পারে যতটা আমি জানি।
সিবারসিটিজেন 1

3
@ দিমিত্রিজাইতসেভ অন্য কোনও ধরণের (প্রত্যাশিত বাস্তবের চেয়ে আলাদা) কোনও কিছুর ভূমিকা পালন করতে পারে না। কথাটি নয়। উদাহরণস্বরূপ, বিষয়টি হ'ল কীভাবে শৃঙ্খলে যখন পূর্ববর্তীটি অপ্রত্যাশিত মানের ধরণটি পরেরটিকে আবদ্ধ করতে পারে (কেবলমাত্র একটি রিয়েলকে কেবল একটি ইনপুট হিসাবে গ্রহণ না করে) কোনও শৃঙ্খলে কীভাবে রূপান্তর করতে পারে।
সিবারসিটিজেন 1

3
আর একটি বিভ্রান্তির বিষয় হ'ল "মোনাড" শব্দটি আপনার উত্তরে কেবলমাত্র দু'বার প্রদর্শিত হয়েছে, এবং কেবলমাত্র অন্যান্য পদগুলির সাথে একত্রিত - Stateএবং IO, এর মধ্যে কোনওটির সাথেই "মোনাড" এর সঠিক অর্থ দেওয়া হচ্ছে না
দিমিত্রি জায়েতসেভ

31
আমার কাছে একজন ওওপি ব্যাকগ্রাউন্ড থেকে আগত একজন ব্যক্তি হিসাবে এই উত্তরটি একটি মোনাড থাকার পেছনের অনুপ্রেরণাটি এবং মোনাদ আসলে কী কী তা আরও ভালভাবে ব্যাখ্যা করেছে (এটি আরও অনেকটা স্বীকৃত উত্তর)। সুতরাং, আমি এটি খুব সহায়ক বলে মনে করি। অনেক ধন্যবাদ @ সিবারসিটিয়েন 1 এবং +1
অখিললেস

3
আমি প্রায় এক বছর ধরে ফাংশনাল প্রোগ্রামিং বন্ধ এবং চালু নিয়ে পড়ছি। এই উত্তরটি এবং বিশেষত প্রথম দুটি বিষয় শেষ পর্যন্ত আমাকে বুঝতে বাধ্য করেছে যে অত্যাবশ্যক প্রোগ্রামিংয়ের অর্থ কী, এবং কার্যকরী প্রোগ্রামিং কেন আলাদা। ধন্যবাদ!
জারহালি

82

আমি বলব মনাদের নিকটতম ওও উপমাটি হ'ল " কমান্ড প্যাটার্ন "।

কমান্ড প্যাটার্নে আপনি একটি কমান্ড অবজেক্টে একটি সাধারণ বিবৃতি বা অভিব্যক্তি মোড়ানো । কমান্ড অবজেক্ট একটি এক্সিকিউট পদ্ধতি প্রকাশ করে যা মোড়ানো বিবৃতি কার্যকর করে। সুতরাং বিবৃতিটি প্রথম শ্রেণীর অবজেক্টগুলিতে রূপান্তরিত হয় যা চারপাশে পাস এবং ইচ্ছায় কার্যকর করা যেতে পারে। কমান্ডগুলি রচনা করা যায় যাতে আপনি কমান্ড-অবজেক্টগুলিকে শৃঙ্খলাবদ্ধ করে বাসা বেঁধে একটি প্রোগ্রাম-অবজেক্ট তৈরি করতে পারেন।

কমান্ডগুলি একটি পৃথক বস্তু, চালক দ্বারা কার্যকর করা হয় । কমান্ড প্যাটার্নটি ব্যবহারের সুবিধা (কেবলমাত্র সাধারণ বিবৃতিগুলির একটি ধারাবাহিক সম্পাদন না করে) হ'ল কমান্ডগুলি কীভাবে কার্যকর করা উচিত সে সম্পর্কে বিভিন্ন চালকরা বিভিন্ন যুক্তি প্রয়োগ করতে পারেন।

কমান্ড প্যাটার্নটি ভাষা বৈশিষ্ট্যগুলি যোগ করতে (বা অপসারণ) করতে ব্যবহার করা যেতে পারে যা হোস্ট ভাষা দ্বারা সমর্থিত নয়। উদাহরণস্বরূপ, ব্যতিক্রম ছাড়াই একটি হাইপোথিটিকাল ওও ভাষায়, আপনি কমান্ডগুলিতে "চেষ্টা" এবং "নিক্ষেপ" পদ্ধতিগুলি প্রকাশ করে ব্যতিক্রম শব্দার্থ যুক্ত করতে পারেন add যখন কোনও কমান্ড নিক্ষেপ কল করে, সর্বশেষ "চেষ্টা করুন" কল না হওয়া পর্যন্ত চালকরা কমান্ডের তালিকা (বা গাছ) এর মাধ্যমে ব্যাকট্র্যাক করে। বিপরীতভাবে, আপনি পৃথক কমান্ডের দ্বারা ছড়িয়ে দেওয়া সমস্ত ব্যতিক্রমগুলি ধরে ফেললে এবং পরবর্তী কমান্ডে প্রেরিত ত্রুটি কোডগুলিতে রূপান্তর করে আপনি কোনও ভাষা থেকে ব্যতিক্রমী শব্দগুলির ব্যতিক্রম (যদি আপনি ব্যতিক্রমগুলি খারাপ বলে বিশ্বাস করেন ) সরিয়ে ফেলতে পারেন ।

আরও বেশি অভিনব এক্সিকিউশন সিনটেমিকস যেমন লেনদেন, অ-নিরস্তামূলক প্রয়োগ বা ধারাবাহিকতা এমন ভাষায় প্রয়োগ করা যেতে পারে যা এটিকে স্থানীয়ভাবে সমর্থন করে না। আপনি যদি এটি সম্পর্কে চিন্তা করেন তবে এটি একটি দুর্দান্ত শক্তিশালী প্যাটার্ন।

এখন বাস্তবে কমান্ড-নিদর্শনগুলি সাধারণ ভাষার বৈশিষ্ট্য হিসাবে ব্যবহার করা হয় না। প্রতিটি বিবৃতিকে একটি পৃথক শ্রেণিতে পরিণত করার ওভারহেড বয়লারপ্লেট কোডটি অসহনীয় পরিমাণে নিয়ে যায়। তবে নীতিগতভাবে এটি এফপিতে সমাধানের জন্য মনড যেমন ব্যবহার করা হয় একই সমস্যাগুলি সমাধান করতে ব্যবহার করা যেতে পারে।


15
আমি বিশ্বাস করি এটি আমি দেখেছি এটিই প্রথম মোনাড ব্যাখ্যা যা কার্যকরী প্রোগ্রামিং ধারণার উপর নির্ভর করে না এবং এটি বাস্তব ওওপি পদগুলিতে রাখেনি। সত্যিই ভাল উত্তর।
ডেভিড কে। হেস

এটি এফপি / হাস্কেল-এ আসলে ম্যানডগুলি আসলে খুব নিকটেই রয়েছে, কেবল কমান্ডটি "জানে" যার সাথে "অনুরোধ যুক্তি" তারা অন্তর্ভুক্ত করে (এবং কেবল সামঞ্জস্যপূর্ণ একসাথে বেঁধে রাখা যেতে পারে); চালক কেবল প্রথম মান সরবরাহ করে। এটি "প্রিন্ট" কমান্ডটি "অ-নিরঙ্কুশনের কার্যকর প্রয়োগের যুক্তি" দ্বারা কার্যকর করা যায় না। না, এটি "আই / ও যুক্তি" হতে হবে (অর্থাত্ আইও মোনাড)। তবে এটি ছাড়াও এটি খুব কাছে। এমনকি আপনি এমনকি বলতে পারেন যে মনাদাসগুলি কেবলমাত্র প্রোগ্রাম (কোড বিবৃতি দিয়ে তৈরি, পরে কার্যকর করা হবে)। প্রথম দিনগুলিতে "বাঁধাই" সম্পর্কে "প্রোগ্রামেবল সেমিকোলন" হিসাবে কথা হয়েছিল ।
নেস

1
@ ডেভিডকে.হেস আমি যে উত্তরগুলি বুনিয়াদি এফপি ধারণাগুলি ব্যাখ্যা করার জন্য এফপি ব্যবহার করি এবং বিশেষত উত্তরগুলি যে স্কালার মতো একটি এফপি ভাষা ব্যবহার করে সেগুলি সম্পর্কে আমি অবিশ্বাস্যভাবে সন্দেহবাদী। ভাল হয়েছে, জ্যাকবিবি!
মনিকা

62

কোনও ওওপি প্রোগ্রামার বুঝতে পারে (কোনও কার্যকরী প্রোগ্রামিং ব্যাকগ্রাউন্ড ছাড়াই), মোনাদ কী?

এটি কোন সমস্যার সমাধান করে এবং এটি ব্যবহৃত সবচেয়ে সাধারণ জায়গা কোনটি ব্যবহৃত হয়?

ওও প্রোগ্রামিংয়ের ক্ষেত্রে, একটি মোনাড হ'ল একটি ইন্টারফেস (বা সম্ভবত মিক্সিন) হয়, যা দুটি পদ্ধতি সহ একটি ধরণের মাধ্যমে প্যারামিটারাইজড হয় returnএবং bindযা বর্ণনা করে:

  • কীভাবে ইনজেকশনের মান ধরণের মানডিক মান পেতে একটি মান ইনজেক্ট করতে হয়;
  • কোনও ফাংশন কীভাবে ব্যবহার করতে হবে যা কোনও অ-মোনাডিকের কাছ থেকে এক একাত্মক মান তৈরি করে, একটি একক মানকে।

এটি যে সমস্যার সমাধান করে তা হ'ল একই ধরণের সমস্যা যা আপনি কোনও ইন্টারফেস থেকে আশা করতে পারেন, যথা, "আমার কাছে বিভিন্ন শ্রেণীর একটি গুচ্ছ রয়েছে যা বিভিন্ন কাজ করে, তবে মনে হয় সেই বিভিন্ন জিনিসগুলি এমনভাবে করা যায় যার অন্তর্নিহিত মিল রয়েছে How কীভাবে আমি কি তাদের মধ্যে সেই মিলটি বর্ণনা করতে পারি, এমনকি যদি ক্লাসগুলি নিজেরাই 'অবজেক্ট' শ্রেণির চেয়ে খুব নিকটে কোনও কিছুর উপপ্রকার না হয়? "

আরও নির্দিষ্টভাবে, Monad"ইন্টারফেস" এর অনুরূপIEnumerator বা IIteratorএটি নিজেই একটি টাইপ নেয় যা একটি টাইপ নেয়। যদিও প্রধান "পয়েন্ট" Monadঅভ্যন্তর প্রকারের উপর ভিত্তি করে ক্রিয়াকলাপ সংযোগ করতে সক্ষম হয়, এমনকি নতুন "অভ্যন্তরীণ ধরণের" থাকার বিন্দুতে, এমনকি - বা এমনকি বর্ধন করে - মূল শ্রেণীর তথ্য কাঠামো রাখে।


1
returnআসলে মোনাডে কোনও পদ্ধতি হবে না, কারণ এটি একটি মোনাডের উদাহরণটিকে আর্গুমেন্ট হিসাবে গ্রহণ করে না। (যেমন: এটি কোনও / স্ব নেই)
লরেন্স গনসালভেস

@ লরেন্সগনসালভস: যেহেতু আমি বর্তমানে আমার স্নাতক থিসিসটি অনুসন্ধান করছি তাই আমার মনে হয় যে সি # / জাভাতে ইন্টারফেসে স্থির পদ্ধতির অভাব বেশিরভাগ ক্ষেত্রেই সীমাবদ্ধ। আপনি পুরো মোনাডের কাহিনী বাস্তবায়নের দিকে অনেক দূরে যেতে পারেন, টাইপক্লাসের ভিত্তিতে কমপক্ষে স্থিতিশীলভাবে আবদ্ধ। মজার বিষয় হল, উচ্চ ধরণের ধরণের অভাব সত্ত্বেও এটি কাজ করবে।
সেবাস্তিয়ান গ্রাফ

42

ক্রিস্টোফার লিগের (জুলাই 12, 2010) দ্বারা আপনার সাম্প্রতিক উপস্থাপনা " মোনাডোলজি - প্রকার উদ্বেগ সম্পর্কিত পেশাদার সহায়তা " রয়েছে যা ধারাবাহিকতা এবং মোনাডের বিষয়গুলিতে বেশ আকর্ষণীয়। এই (স্লাইডসারে) উপস্থাপনাটির সাথে ভিডিওটি আসলে ভিমেও উপলভ্য

এই এক ঘন্টা ভিডিওতে মোনাড অংশটি প্রায় 37 মিনিটের মধ্যেই শুরু হয় এবং 58 টি স্লাইড উপস্থাপনার স্লাইড 42 দিয়ে শুরু হয়।

এটি "ফাংশনাল প্রোগ্রামিংয়ের শীর্ষস্থানীয় নকশার প্যাটার্ন" হিসাবে উপস্থাপিত হয়েছে, তবে উদাহরণগুলিতে ব্যবহৃত ভাষা স্কালা, যা ওওপি এবং কার্যক্ষম উভয়ই। দেবাশীষ ঘোষ (২ 27 শে মার্চ, ২০০ )) থেকে
" মোনাডস - স্কালায় বিমূর্ত গণনার আরও একটি উপায় " ব্লগ পোস্টে আপনি স্ক্যানের ইন স্ক্যালায় আরও পড়তে পারেন ।

কোনও প্রকারের কনস্ট্রাক্টর এম একটি মান্ড এটি যদি এই অপারেশনগুলিকে সমর্থন করে:

# the return function
def unit[A] (x: A): M[A]

# called "bind" in Haskell 
def flatMap[A,B] (m: M[A]) (f: A => M[B]): M[B]

# Other two can be written in term of the first two:

def map[A,B] (m: M[A]) (f: A => B): M[B] =
  flatMap(m){ x => unit(f(x)) }

def andThen[A,B] (ma: M[A]) (mb: M[B]): M[B] =
  flatMap(ma){ x => mb }

উদাহরণস্বরূপ (স্কালায়):

  • Option একটি monad হয়
    ডিফ ইউনিট [এ] (এক্স: এ): বিকল্প [এ] = কিছু (এক্স)

    Def ফ্ল্যাটম্যাপ [এ, বি] (এম: বিকল্প [এ]) (এফ: এ => বিকল্প [বি]): বিকল্প [বি] =
      মি ম্যাচ {
       কেস কোনটি নয়>> কিছুই নয়
       কেস কিছু (x) => চ (এক্স)
      }
  • List মোনাদ
    ডিফ ইউনিট [এ] (এক্স: এ): তালিকা [এ] = তালিকা (এক্স)

    Def ফ্ল্যাটম্যাপ [এ, বি] (এম: তালিকা [এ]) (চ: এ => তালিকা [বি]): তালিকা [বি] =
      মি ম্যাচ {
        কেস নিল => নীল
        কেস এক্স :: এক্সএস => এফ (এক্স) ::: ফ্ল্যাটম্যাপ (এক্সএস) (চ)
      }

মনাদ কাঠামোগত সুবিধার্থে তৈরি সুবিধাজনক সিনট্যাক্সের কারণে স্কালায় মোনাদ একটি বড় বিষয়:

forস্ক্যালায় অনুধাবন :

for {
  i <- 1 to 4
  j <- 1 to i
  k <- 1 to j
} yield i*j*k

সংকলক দ্বারা অনুবাদ করা হয়েছে:

(1 to 4).flatMap { i =>
  (1 to i).flatMap { j =>
    (1 to j).map { k =>
      i*j*k }}}

মূল বিমূর্ততা হ'ল flatMap, যা শৃঙ্খলার মাধ্যমে গণনাটিকে আবদ্ধ করে।
প্রতিটি অনুরোধ flatMapএকই ডাটা স্ট্রাকচার ধরণের (তবে বিভিন্ন মানের) প্রদান করে, যা পরবর্তী কমান্ডের শৃঙ্খলে ইনপুট হিসাবে কাজ করে।

উপরের স্নিপেটে ফ্ল্যাটম্যাপ ইনপুট হিসাবে ক্লোজার হিসাবে নেয় এবং এটিকে (SomeType) => List[AnotherType]রিটার্ন দেয় List[AnotherType]। গুরুত্বপূর্ণ লক্ষণীয় বিষয় হ'ল সমস্ত ফ্ল্যাটম্যাপগুলি সমাপ্তির ধরণটিকে ইনপুট হিসাবে একই রকম নেয় এবং একই ধরণের আউটপুট হিসাবে ফেরত দেয়।

এটিই গণনার থ্রেডকে "আবদ্ধ" করে - বোধগম্যতায় ক্রমের প্রতিটি আইটেমকে এই একই ধরণের প্রতিবন্ধকে সম্মান জানাতে হয়।


যদি আপনি দুটি অপারেশন নেন (এটি ব্যর্থ হতে পারে) এবং তৃতীয়টিতে ফলাফলটি পাস করেন, যেমন:

lookupVenue: String => Option[Venue]
getLoggedInUser: SessionID => Option[User]
reserveTable: (Venue, User) => Option[ConfNo]

তবে মোনাডের সুবিধা না নিয়েই আপনি কনওলিউটেড ওওপি-কোডের মতো পান:

val user = getLoggedInUser(session)
val confirm =
  if(!user.isDefined) None
  else lookupVenue(name) match {
    case None => None
    case Some(venue) =>
      val confno = reserveTable(venue, user.get)
      if(confno.isDefined)
        mailTo(confno.get, user.get)
      confno
  }

যদিও মোনাডের সাথে, আপনি সমস্ত ক্রিয়াকলাপের মতো প্রকৃত প্রকারের ( Venue, User) সাথে কাজ করতে পারেন এবং বিকল্প বাক্যটি সিনট্যাক্সের ফ্ল্যাটম্যাপের কারণে গোপন রাখতে পারেন hidden

val confirm = for {
  venue <- lookupVenue(name)
  user <- getLoggedInUser(session)
  confno <- reserveTable(venue, user)
} yield {
  mailTo(confno, user)
  confno
}

তিনটি ফাংশন থাকলেই ফলনের অংশটি কার্যকর করা হবে Some[X]; যে Noneকোনওকে সরাসরি ফিরিয়ে দেওয়া হবে confirm


তাই:

মনডস ফাংশনাল প্রোগ্রামিংয়ের মধ্যে অর্ডার করা গণনার অনুমতি দেয় যা আমাদের ডিএসএলের মতো কিছুটা সুন্দর কাঠামোবদ্ধ আকারে ক্রমগুলির ক্রম মডেল করতে দেয়।

এবং সর্বাধিক শক্তিটি বিভিন্ন অ্যাপ্লিকেশনটির মধ্যে এক্সটেনসিবল অ্যাবস্ট্রাকশনগুলিতে বিভিন্ন উদ্দেশ্যে পরিবেশন করা মনাদগুলি রচনা করার ক্ষমতা নিয়ে আসে।

একটি মোনাড দ্বারা ক্রমের এই ক্রম এবং থ্রেডিং ভাষা সংকলক দ্বারা সম্পন্ন হয় যা ক্লোজারের যাদুতে রূপান্তর করে।


যাইহোক, মোনাড কেবল এফপিতে ব্যবহৃত গণনার মডেল নয়:

বিভাগ তত্ত্ব গণনার অনেক মডেল প্রস্তাব করে। তাদের মধ্যে

  • গণনার তীর মডেল
  • গণনার মোনাড মডেল
  • গণনার প্রয়োগকারী মডেল

2
আমি এই ব্যাখ্যা ভালোবাসি! আপনি যে উদাহরণটি দিয়েছেন তা ধারণাটি সুন্দরভাবে ফুটিয়ে তুলেছে এবং এটিও যোগ করে যে আইএমএইচও এরিকের টিজার থেকে সিলেক্টম্যানির () একটি মোনাড হওয়ার বিষয়ে কি অনুপস্থিত ছিল। এর জন্য থেক্স!
aoven

1
IMHO এটি সবচেয়ে মার্জিত উত্তর
পলিমারেজ

এবং অন্য কিছুর আগে, ফান্টেক্টর।
নেস 18

34

দ্রুত পাঠকদের সম্মান জানাতে, আমি প্রথমে সুনির্দিষ্ট সংজ্ঞা দিয়ে শুরু করি, দ্রুত আরও "সরল ইংরাজী" ব্যাখ্যার সাথে চালিয়ে যাই এবং তারপরে উদাহরণগুলিতে চলে যাই।

এখানে সংক্ষিপ্ত এবং সুনির্দিষ্ট সংজ্ঞা উভয়ই দেওয়া হয়েছে :

একটি মোনাড (কম্পিউটার বিজ্ঞানে) আনুষ্ঠানিকভাবে একটি মানচিত্র যা:

  • Xপ্রদত্ত প্রোগ্রামিং ভাষার প্রতিটি প্রকারকে একটি নতুন প্রকারে প্রেরণ করে T(X)("ধরণের Tমানগুলির সাথে X" -কম্প্যাটেশন "বলা হয় );

  • ফর্মের দুটি ফাংশন রচনা করার জন্য f:X->T(Y)এবং g:Y->T(Z)একটি কার্যক্রমে একটি বিধি দ্বারা সজ্জিত g∘f:X->T(Z);

  • একটি উপায়ে যা স্পষ্টভাবে অর্থে সংঘবদ্ধ এবং একটি প্রদত্ত ইউনিট ফাংশন সম্পর্কে সম্মতিহীন pure_X:X->T(X), খাঁটি গণনার যে একটি মূল্য গ্রহণ করে যা কেবল সেই মান ফেরায় বলে মনে করা হয়।

সুতরাং সহজ কথায়, একটি মোনাড হ'ল একটি বিধি যা কোনও প্রকার Xথেকে অন্য প্রকারে যাওয়ারT(X) , এবং দুটি ফাংশন থেকে পাস করার নিয়ম f:X->T(Y)এবং g:Y->T(Z)(যা আপনি রচনা করতে চান তবে পারছেন না) একটি নতুন ফাংশনেh:X->T(Z) । যা অবশ্য কড়া গাণিতিক অর্থে রচনা নয়। আমরা মূলত ফাংশনটির রচনা "নমন" করছি বা কীভাবে কার্যগুলি রচনা করা হয়েছে তা পুনরায় সংজ্ঞায়িত করছি।

এছাড়াও, "স্পষ্ট" গাণিতিক অক্ষগুলি সন্তুষ্ট করার জন্য আমাদের মোনাডের রচনার নিয়ম প্রয়োজন:

  • সহযোগিতা : এর সাথে কমপোজ fকরা gএবং তারপরে h(বাইরে থেকে) রচনা gকরা hএবং তারপরে f(ভিতর থেকে) সমান হওয়া উচিত ।
  • একজাতীয় সম্পত্তি : উভয় পক্ষের পরিচয় ফাংশনটি রচনা fকরলে ফলন পাওয়া উচিত ।f

আবার সহজ কথায়, আমরা আমাদের ফাংশন রচনাটিকে আমাদের পছন্দ মতো পুনরায় সংজ্ঞায়িত করতে পাগল হতে পারি না:

  • আমাদের প্রথমে সংঘবদ্ধতা প্রয়োজন যাতে একটি সারিতে বেশ কয়েকটি ফাংশন রচনা করতে সক্ষম হয় f(g(h(k(x))), এবং ক্রম জোড়ের ক্রম সংশ্লেষ নির্দিষ্ট করে দেওয়ার বিষয়ে চিন্তা করার দরকার নেই। যেহেতু মোনাড নিয়মটি কেবলমাত্র কোনও জোড়া ফাংশন রচনা করবেন তা নির্ধারণ করে , সেই অক্ষিপ্ত ব্যতীত, আমাদের জানতে হবে কোন জোড়াটি প্রথমে রচনা করা হয়েছে ইত্যাদি ইত্যাদি। (নোট যে commutativity সম্পত্তি যে থেকে ভিন্ন fসঙ্গে স্থিরীকৃত gএকই মত ছিল gসঙ্গে স্থিরীকৃত f, যা প্রয়োজন হয় না)।
  • এবং দ্বিতীয়ত, আমাদের একচেটিয়া সম্পত্তি প্রয়োজন, যা সহজভাবে বলতে গেলে পরিচয়গুলি তুচ্ছভাবে রচনা করে যা আমরা তাদের প্রত্যাশা করি। সুতরাং যখনই এই পরিচয়গুলি বের করা যায় আমরা নিরাপদে ফাংশনগুলি রিফেক্টর করতে পারি।

আবার সংক্ষেপে: একটি মোনাড হ'ল প্রকারের সম্প্রসারণ এবং রচনা ফাংশনগুলির নিয়ম যা দুটি অক্ষরকেই সন্তুষ্ট করে - সংস্থান এবং একক সম্পত্তি।

ব্যবহারিক শর্তে, আপনি চান যে ভাষা, সংকলক বা কাঠামো যা আপনার জন্য রচনামূলক ক্রিয়াকলাপের যত্ন নেবে সেই মোনাদ আপনার জন্য প্রয়োগ করা হোক। সুতরাং তাদের কার্যকারিতা কীভাবে কার্যকর করা হয় তা চিন্তা করার চেয়ে আপনি নিজের ফাংশনের যুক্তি লেখার দিকে মনোনিবেশ করতে পারেন।

সংক্ষেপে এটি মূলত এটি।


পেশাদারী গণিতজ্ঞ হচ্ছে, আমি কলিং এড়ানোর জন্য পছন্দ করা hএর "রচনা" fএবং g। গাণিতিক কারণ, এটি না। এটিকে "রচনা" বললে ভুলভাবে অনুমান করা hযায় এটিই আসল গাণিতিক রচনা, যা তা নয়। এমনকি এটি দ্বারা fএবং অনন্যভাবে নির্ধারিত হয় না g। পরিবর্তে, এটি আমাদের মোনাডের নতুন "রচনা রচনা" ফাংশনগুলির ফলাফল। যা পরেরটি উপস্থিত থাকলেও প্রকৃত গাণিতিক রচনা থেকে সম্পূর্ণ আলাদা হতে পারে!


এটিকে কম শুকনো করার জন্য, আমি এটি উদাহরণ দিয়ে উদাহরণ দিয়ে বোঝানোর চেষ্টা করি যে আমি ছোট বিভাগগুলি দিয়ে মন্তব্য করছি, যাতে আপনি ঠিক বিন্দুতে এড়াতে পারেন।

ব্যতিক্রম মোনাড উদাহরণ হিসাবে নিক্ষেপ

মনে করুন আমরা দুটি ফাংশন রচনা করতে চাই:

f: x -> 1 / x
g: y -> 2 * y

তবে f(0)সংজ্ঞায়িত করা হয় না, সুতরাং একটি ব্যতিক্রম eছুঁড়ে দেওয়া হয়। তাহলে আপনি কম্পোজিশনাল মানটি কীভাবে সংজ্ঞায়িত করতে পারেন g(f(0))? আবারও ব্যতিক্রম ছুঁড়ে ফেলুন অবশ্যই! সম্ভবত একই e। হতে পারে একটি নতুন আপডেট ব্যতিক্রম e1

এখানে ঠিক কী ঘটে? প্রথমত, আমাদের নতুন ব্যতিক্রমের মান (বিভিন্ন বা একই) প্রয়োজন। আপনি তাদেরকে কল করতে পারেন nothingবা nullবা যাই হোক না কেন কিন্তু সারাংশ অবশেষ একই - তারা নতুন মান, যেমন হওয়া উচিত তা করা উচিত হবে না numberআমাদের উদাহরণে এখানে। nullযে nullকোনও নির্দিষ্ট ভাষায় কীভাবে প্রয়োগ করা যেতে পারে সে সম্পর্কে বিভ্রান্তি এড়াতে আমি তাদের ফোন না করার পছন্দ করি । সমানভাবে আমি এড়াতে পছন্দ করি nothingকারণ এটি প্রায়শই যুক্ত হয় nullযা নীতিগতভাবে যা করা nullউচিত তা হল, যাইহোক, যে নীতিটি প্রায়শই ব্যবহারিক কারণেই বেঁকে যায়।

ব্যতিক্রম ঠিক কি?

এটি যে কোনও অভিজ্ঞ প্রোগ্রামারের কাছে একটি তুচ্ছ বিষয় তবে আমি যে কোনও বিভ্রান্তির কীট নিঃশেষ করতে কয়েকটা শব্দ ফেলে দিতে চাই:

ব্যতিক্রম হ'ল মৃত্যুদন্ড কার্যকর করার অকার্যকর ফলাফলটি কীভাবে ঘটে সে সম্পর্কে তথ্য encapsulating object

এটি কোনও বিবরণ ছুঁড়ে ফেলা এবং একক বিশ্বব্যাপী মান (যেমন NaNবা null) প্রত্যাবর্তন করা বা দীর্ঘ লগ তালিকা তৈরি করা বা ঠিক কী ঘটেছিল তা কোনও ডাটাবেসে প্রেরণ এবং বিতরণকৃত ডেটা স্টোরেজ স্তরটিতে অনুলিপি করা থেকে শুরু করে;)

ব্যতিক্রমের এই দুটি চরম উদাহরণগুলির মধ্যে গুরুত্বপূর্ণ পার্থক্যটি হ'ল প্রথম ক্ষেত্রে কোনও পার্শ্ব প্রতিক্রিয়া নেই । দ্বিতীয়টিতে আছে। যা আমাদের (হাজার ডলার) প্রশ্নে নিয়ে আসে:

খাঁটি ফাংশনে ব্যতিক্রম অনুমোদিত?

সংক্ষিপ্ত উত্তর : হ্যাঁ, তবে কেবল তখনই যখন তারা পার্শ্ব-প্রতিক্রিয়া দেখায় না।

দীর্ঘ উত্তর। খাঁটি হতে, আপনার ফাংশনটির আউটপুট অবশ্যই তার ইনপুট দ্বারা স্বতন্ত্রভাবে নির্ধারণ করা উচিত। সুতরাং আমরা আমাদের ব্যতিক্রমটিকে যে নতুন বিমূর্ত মানকে fপাঠিয়ে আমাদের সংশোধন করি। আমরা নিশ্চিত করে নিই যে মানটিতে বাইরের কোনও তথ্য নেই যা আমাদের ইনপুট দ্বারা অনন্যভাবে নির্ধারিত হয় না, যা । তাই পার্শ্ব-প্রতিক্রিয়া ব্যতীত ব্যতিক্রমের উদাহরণ এখানে:0eex

e = {
  type: error, 
  message: 'I got error trying to divide 1 by 0'
}

এবং এখানে পার্শ্ব-প্রতিক্রিয়া সহ একটি:

e = {
  type: error, 
  message: 'Our committee to decide what is 1/0 is currently away'
}

প্রকৃতপক্ষে, কেবলমাত্র যদি সেই বার্তাটি ভবিষ্যতে পরিবর্তিত হতে পারে তবে এর কেবলমাত্র পার্শ্ব-প্রতিক্রিয়া রয়েছে। তবে যদি এটি কখনই পরিবর্তিত না হওয়ার গ্যারান্টিযুক্ত হয় তবে সেই মানটি অনন্যভাবে অনুমানযোগ্য হয়ে যায় এবং তাই কোনও পার্শ্ব-প্রতিক্রিয়া নেই।

এটি আরও সিলিয়ার করতে। কোনও ফাংশন ফিরে আসা 42পরিষ্কারভাবে খাঁটি। তবে যদি ক্রেজি 42কোনও মান পরিবর্তন করতে পারে এমন পরিবর্তনশীল করার সিদ্ধান্ত নেয় , তবে একই শর্তটি নতুন অবস্থার অধীনে খাঁটি হওয়া বন্ধ করে দেয়।

নোট করুন যে সারটিটি প্রদর্শনের জন্য আমি বস্তুর আক্ষরিক স্বরলিপি ব্যবহার করছি। দুর্ভাগ্যক্রমে জাভাস্ক্রিপ্টের মতো ভাষাগুলিতে জিনিসগুলি গণ্ডগোলিত হয়, যেখানে errorফাংশন রচনার ক্ষেত্রে আমরা এখানে যা চাই তার সাথে আচরণ করে এমন কোনও ধরণ নেই, যেখানে প্রকৃত প্রকারগুলি এইভাবে আচরণ করে না nullবা NaNবরং কিছু কৃত্রিম এবং সর্বদা স্বজ্ঞাত নয় through রূপান্তর টাইপ করুন।

প্রকার প্রসারিত করুন

যেহেতু আমরা আমাদের ব্যতিক্রমের ভিতরে বার্তাটি পৃথক করতে চাই, আমরা সত্যই Eপুরো ব্যতিক্রম বস্তুর জন্য একটি নতুন ধরণের ঘোষণা করছি এবং maybe numberতার বিভ্রান্তিকর নাম বাদে এটিই করে যা কোনও প্রকারের numberবা নতুন ব্যতিক্রম প্রকারের E, তাই এটি সত্যিই ইউনিয়নের number | Eএর numberএবং E। বিশেষত, এটি নির্ভর করে যে আমরা কীভাবে নির্মাণ করতে চাই E, যা নামটিতে প্রস্তাবিত বা প্রতিফলিত হয় না maybe number

ক্রিয়ামূলক রচনা কি?

এটি গাণিতিক অপারেশন ফাংশন গ্রহণ করে f: X -> Yএবং g: Y -> Zতাদের রচনাটি কার্যকরী h: X -> Zসন্তোষজনক হিসাবে তৈরি করে h(x) = g(f(x))। এই সংজ্ঞাটি নিয়ে সমস্যাটি তখন ঘটে যখন ফলাফলকে f(x)যুক্তি হিসাবে অনুমোদিত করা হয় না g

গণিতে সেই কাজগুলি অতিরিক্ত কাজ ছাড়া রচনা করা যায় না। আমাদের উপরোক্ত উদাহরণগুলির কঠোরভাবে গাণিতিক সমাধান fএবং এর সংজ্ঞা সেট থেকে gসরিয়ে 0দেওয়া f। সেই সংজ্ঞায়নের নতুন সেট (নতুন আরও নিয়ন্ত্রিত ধরণের ধরণের x) সাথে, fএটি কম্পোজেবল হয়ে ওঠে g

যাইহোক, এটির fমতো সংজ্ঞা সেটকে সীমাবদ্ধ করার জন্য প্রোগ্রামিংয়ে এটি খুব ব্যবহারিক নয় । পরিবর্তে, ব্যতিক্রম ব্যবহার করা যেতে পারে।

অথবা অন্য পদ্ধতির যেমন, কৃত্রিম মান মত নির্মিত NaN, undefined, null, Infinityইত্যাদি সুতরাং আপনি মূল্যায়ন 1/0করার Infinityএবং 1/-0করতে -Infinity। এবং তারপরে ব্যতিক্রম ছোঁড়ার পরিবর্তে নতুন অভিব্যক্তিটিকে আপনার অভিব্যক্তিতে ফিরিয়ে আনতে বাধ্য করুন। আপনি ভবিষ্যদ্বাণীযোগ্য বা নাও পেতে পারে ফলাফলের দিকে পরিচালিত:

1/0                // => Infinity
parseInt(Infinity) // => NaN
NaN < 0            // => false
false + 1          // => 1

এবং আমরা নিয়মিত সংখ্যায় ফিরে এসেছি এগিয়ে যাওয়ার জন্য প্রস্তুত;)

জাভাস্ক্রিপ্ট আমাদের উপরের উদাহরণ হিসাবে ত্রুটি না ছুঁড়ে দিয়ে যে কোনও মূল্যে সংখ্যাসূচক এক্সপ্রেশন চালিয়ে যেতে দেয়। এর অর্থ এটি ফাংশন রচনা করতে দেয়। কোনটি মোনাদ সম্পর্কে ঠিক তাই - এটি এই উত্তরের শুরুতে সংজ্ঞায়িতভাবে অক্ষগুলি সন্তুষ্ট করে ফাংশন রচনা করার নিয়ম।

তবে একটি সংখ্যার ত্রুটিগুলি মোকাবেলার জন্য জাভাস্ক্রিপ্টের প্রয়োগ থেকে উদ্ভূত ফাংশন রচনা করার নিয়মটি কী?

এই প্রশ্নের উত্তর দেওয়ার জন্য আপনার কেবলমাত্র অ্যাকিয়মগুলি পরীক্ষা করা (এখানে প্রশ্নের অংশ হিসাবে ব্যায়াম হিসাবে রেখে দেওয়া হয়েছে) পরীক্ষা করা উচিত।

একটি ছদ্মরূপ নির্মাণের জন্য কি ছোঁড়া ব্যতিক্রম ব্যবহার করা যেতে পারে?

প্রকৃতপক্ষে, আরও কার্যকর মোনাডের পরিবর্তে নিয়মটি হ'ল যদি কারও fজন্য ব্যতিক্রম ছুঁড়ে ফেলা হয় x, তবে এর রচনাটি যে কোনওটির সাথেও রয়েছে gEপ্লাসটি শুধুমাত্র একমাত্র সম্ভাব্য মান ( শ্রেণির তত্ত্বের টার্মিনাল অবজেক্ট ) দিয়ে ব্যতিক্রমটিকে বিশ্বব্যাপী অনন্য করে তুলুন । এখন দুটি অক্ষর তাত্ক্ষণিকভাবে চেকযোগ্য এবং আমরা একটি খুব দরকারী মনাদ পেয়েছি। এবং ফলাফলটি সম্ভবত মোনাদ হিসাবে সুপরিচিত ।


3
ভাল অবদান। +1 তবে আপনি মুছে ফেলতে চাইবেন "বেশিরভাগ ব্যাখ্যা খুব দীর্ঘ খুঁজে পেয়েছেন ..." আপনার পক্ষে এটিকে সবচেয়ে দীর্ঘতম বলে মনে হচ্ছে। অন্যরা যদি প্রশ্ন হিসাবে "প্লেইন ইংলিশ" হয় তবে তা বিচার করবেন: "সরল ইংরেজী == সরল কথায়, একটি সহজ উপায়ে"।
সিবারসিটিজেন 1

@ সিবারসিটিজন 1 ধন্যবাদ! এটি উদাহরণস্বরূপ ছোট, যদি আপনি উদাহরণটি গণনা করেন না। মূল কথাটি হ'ল সংজ্ঞাটি বোঝার জন্য আপনাকে উদাহরণটি পড়ার দরকার নেই । দুর্ভাগ্যক্রমে অনেক ব্যাখ্যা আমাকে প্রথমে উদাহরণগুলি পড়তে বাধ্য করে , যা প্রায়শই অপ্রয়োজনীয় তবে অবশ্যই লেখকের জন্য অতিরিক্ত কাজের প্রয়োজন হতে পারে। নির্দিষ্ট উদাহরণগুলির উপর অত্যধিক নির্ভরতার সাথে, এমন একটি বিপদ রয়েছে যে অযৌক্তিক বিবরণগুলি ছবিটিকে অস্পষ্ট করে তোলে এবং বুঝতে এটি আরও শক্ত করে তোলে। এটি বলার পরে, আপনার বৈধ পয়েন্ট রয়েছে, আপডেটটি দেখুন।
দিমিত্রি জইতসেভ

1
খুব দীর্ঘ এবং বিভ্রান্তিকর
সাদিমুরুগান

1
@ সিনিমুরুগান উন্নয়নের পরামর্শগুলি স্বাগত;)
দিমিত্রি

26

একটি মোনাড একটি ডেটা টাইপ যা কোনও মানকে আবদ্ধ করে এবং যার জন্য মূলত দুটি ক্রিয়াকলাপ প্রয়োগ করা যেতে পারে:

  • return x মোনাড টাইপের একটি মান তৈরি করে যা এনপ্যাপসুলেট করে x
  • m >>= f (এটি "বাইন্ড অপারেটর" হিসাবে পড়ুন) ফাংশনটি প্রয়োগ করে f মোনাদেm

এটিই একটি মোনাড। আরও কয়েকটি প্রযুক্তি রয়েছে তবে মূলত এই দুটি অপারেশন একটি মোনাদকে সংজ্ঞায়িত করে। আসল প্রশ্নটি হ'ল "কোন মোনাদ কী করে ?", এবং এটি মোনাদের উপর নির্ভর করে - তালিকাগুলি হ'ল ম্যানড, মায়বস হ'ল মণাদ, আইও অপারেশনগুলি ম্যানড। এর অর্থ যখন আমরা বলি mon জিনিসগুলি মনবাদস তখন তা হ'ল তাদের মোনড ইন্টারফেসটি রয়েছে returnএবং >>=


"একটি মোনাড কী করে, এবং এটি মোনাদের উপর নির্ভর করে": এবং আরও স্পষ্টভাবে, এটি সেই bindফাংশনের উপর নির্ভর করে যা প্রতিটি মোনাডিক ধরণের জন্য সংজ্ঞায়িত করা উচিত, তাই না? কম্পোজিশনের সাথে বাঁধাই না করাই ভাল কারণ, কারণ এখানে রচনার জন্য একক সংজ্ঞা রয়েছে, যদিও বাইন্ড ফাংশনের জন্য কেবল একটি একক সংজ্ঞা থাকতে পারে না, যদি আমি সঠিকভাবে বুঝতে পারি তবে প্রতি মনডিক প্রকারের একটি রয়েছে।
Hibou57

14

উইকিপিডিয়া থেকে :

ফাংশনাল প্রোগ্রামিংয়ে একটি মোনাড হ'ল এক প্রকারের বিমূর্ত তথ্য টাইপ যা গণনা উপস্থাপন করতে ব্যবহৃত হয় (ডোমেন মডেলের ডেটার পরিবর্তে)। মোনাডস প্রোগ্রামারকে একটি পাইপলাইন তৈরির জন্য ক্রিয়াকলাপগুলি একত্রিত করার অনুমতি দেয়, যাতে প্রতিটি ক্রিয়া মোনাড দ্বারা সরবরাহিত অতিরিক্ত প্রসেসিং বিধি দ্বারা সজ্জিত হয়। ক্রিয়ামূলক শৈলীতে লেখা প্রোগ্রামগুলি কাঠামোগত প্রক্রিয়াগুলিতে মনড ব্যবহার করতে পারে যাতে ক্রমযুক্ত ক্রিয়াকলাপ অন্তর্ভুক্ত থাকে, 1 [2] বা স্বেচ্ছাসেবী নিয়ন্ত্রণ প্রবাহকে সংজ্ঞায়িত করতে (যেমন সামঞ্জস্য পরিচালনা, ধারাবাহিকতা বা ব্যতিক্রমগুলি পরিচালনা করা)।

সাধারণত, দুটি অপারেশন (বাইন্ড এবং রিটার্ন) এবং টাইপ কনস্ট্রাক্টর এম সংজ্ঞায়িত করে একটি মোনাড নির্মিত হয় যা মোনাদিক ফাংশনগুলির সঠিক সংমিশ্রণ (যেমন মনড থেকে মানগুলি তাদের যুক্তি হিসাবে ব্যবহার করে) অনুমোদনের জন্য বিভিন্ন বৈশিষ্ট্য পূরণ করতে হবে। রিটার্ন অপারেশন একটি সরল ধরণের থেকে একটি মান নেয় এবং এটিকে এম টাইপের এক monadic ধারক মধ্যে রাখে বাইন্ড অপারেশনটি বিপরীত প্রক্রিয়া সম্পাদন করে, ধারকটি থেকে মূল মানটি বের করে এবং পাইপলাইনে সম্পর্কিত পরবর্তী কার্যে প্রেরণ করে।

একজন প্রোগ্রামার ডেটা-প্রসেসিং পাইপলাইন সংজ্ঞায়িত করতে মোনাডিক ফাংশন রচনা করবে। মোনাড একটি কাঠামো হিসাবে কাজ করে, কারণ এটি পুনঃব্যবহারযোগ্য আচরণ যা পাইপলাইনে নির্দিষ্ট মোনাডিক ফাংশনগুলি বলা হয় সেই আদেশটি স্থির করে এবং গণনার জন্য প্রয়োজনীয় সমস্ত গোপনীয় কাজ পরিচালনা করে [[3] পাইপলাইনে অন্তর্নির্মিত বাইন্ড এবং রিটার্ন অপারেটরগুলি প্রতিটি monadic ফাংশন রিটার্ন নিয়ন্ত্রণের পরে কার্যকর করা হবে এবং মোনাড দ্বারা পরিচালিত বিশেষ দিকগুলির যত্ন নেবে।

আমি বিশ্বাস করি এটি খুব ভালভাবে ব্যাখ্যা করে।


12

আমি ওওপি শর্তাদি ব্যবহার করে যে সংক্ষিপ্ততম সংজ্ঞাটি পরিচালনা করতে পারি তা করার চেষ্টা করব:

একটি জেনেরিক শ্রেণি CMonadic<T>একটি মোনাড হয় যদি এটি কমপক্ষে নিম্নলিখিত পদ্ধতিগুলি সংজ্ঞায়িত করে:

class CMonadic<T> { 
    static CMonadic<T> create(T t);  // a.k.a., "return" in Haskell
    public CMonadic<U> flatMap<U>(Func<T, CMonadic<U>> f); // a.k.a. "bind" in Haskell
}

এবং যদি নীচের আইনগুলি সমস্ত ধরণের টি এবং তাদের সম্ভাব্য মানগুলির জন্য প্রযোজ্য

বাম পরিচয়:

CMonadic<T>.create(t).flatMap(f) == f(t)

সঠিক পরিচয়

instance.flatMap(CMonadic<T>.create) == instance

associativity:

instance.flatMap(f).flatMap(g) == instance.flatMap(t => f(t).flatMap(g))

উদাহরণ :

একটি তালিকা monad থাকতে পারে:

List<int>.create(1) --> [1]

এবং তালিকার ফ্ল্যাটম্যাপ [1,2,3] এর মতো কাজ করতে পারে:

intList.flatMap(x => List<int>.makeFromTwoItems(x, x*10)) --> [1,10,2,20,3,30]

Iteabless এবং পর্যবেক্ষণগুলিও monadic, পাশাপাশি প্রতিশ্রুতি এবং কাজগুলিও করা যেতে পারে।

ভাষ্য :

মনদেবগুলি তেমন জটিল নয়। flatMapফাংশন আরো সাধারণভাবে সম্মুখীন মত অনেক map। এটি একটি ফাংশন আর্গুমেন্ট (ডেলিগেট নামেও পরিচিত) পায়, যা জেনেরিক শ্রেণীর কাছ থেকে আসা কোনও মান সহ এটি (তাত্ক্ষণিকভাবে বা পরে, শূন্য বা তার বেশি বার) কল করতে পারে। এটি প্রত্যাশা করে যে পাস করা ফাংশনটি একই ধরণের জেনেরিক শ্রেণিতে তার রিটার্নের মানটিও মুড়ে ফেলবে। এটির জন্য সহায়তা করার জন্য, এটি এমন createএকটি নির্মাণকারীর সরবরাহ করে যা একটি মান থেকে সেই জেনেরিক শ্রেণির একটি উদাহরণ তৈরি করতে পারে। ফ্ল্যাটম্যাপের রিটার্ন রেজাল্ট একই ধরণের জেনেরিক ক্লাস, প্রায়শই একই মানগুলি প্যাক করে যা ফ্ল্যাটম্যাপের এক বা একাধিক অ্যাপ্লিকেশনগুলির পূর্বে থাকা মানগুলিতে ফেরতের ফলাফলের মধ্যে ছিল। এটি আপনাকে যতটা চাই ফ্ল্যাটম্যাপ চেইন করতে দেয়:

intList.flatMap(x => List<int>.makeFromTwo(x, x*10))
       .flatMap(x => x % 3 == 0 
                   ? List<string>.create("x = " + x.toString()) 
                   : List<string>.empty())

এটি ঠিক তাই ঘটে যে এই জাতীয় জেনেরিক শ্রেণি বিপুল সংখ্যক জিনিসের জন্য বেস মডেল হিসাবে কার্যকর। এটি (একত্রে বিভাগের তত্ত্বের বর্ণোত্তর সাথে একারণে) কেন মোনাদগুলি বুঝতে বা ব্যাখ্যা করা এত কঠিন বলে মনে হচ্ছে। এগুলি একটি বিমূর্ত জিনিস এবং তারা বিশেষীকরণের পরে কেবল স্পষ্টভাবে কার্যকর হয়ে ওঠে।

উদাহরণস্বরূপ, আপনি monadic পাত্রে ব্যবহার করে ব্যতিক্রমগুলি মডেল করতে পারেন। প্রতিটি ধারক হয় অপারেশনের ফলাফল বা ত্রুটি ঘটেছে। ফ্ল্যাটম্যাপ কলব্যাকের শৃঙ্খলে পরবর্তী ফাংশন (ডেলিগেট) কেবল তখনই বলা হবে যখন পূর্ববর্তীটি ধারকটিতে একটি মান প্যাক করে। অন্যথায় যদি ত্রুটিটি প্যাক করা হয়, ত্রুটিটি শৃঙ্খলযুক্ত পাত্রে untilুকে পড়ে যতক্ষণ না কোনও কন্টেইনার খুঁজে পাওয়া যায় যতক্ষণ না ত্রুটি হ্যান্ডলার ফাংশন সংযুক্ত একটি পদ্ধতির মাধ্যমে সংযুক্ত করা হয় .orElse()(যেমন একটি পদ্ধতি অনুমোদিত অনুমোদিত এক্সটেনশন হবে)

নোটস : কার্যকরী ভাষা আপনাকে এমন ফাংশন লিখতে দেয় যা কোনও একক জেনেরিক শ্রেণীর উপর কাজ করতে পারে। এটি কাজ করার জন্য, এককে মনাদের জন্য একটি জেনেরিক ইন্টারফেস লিখতে হবে। আমি জানি না যে সি # তে এরকম ইন্টারফেস লেখা সম্ভব কিনা, তবে যতদূর আমি জানি এটি এটি নয়:

interface IMonad<T> { 
    static IMonad<T> create(T t); // not allowed
    public IMonad<U> flatMap<U>(Func<T, IMonad<U>> f); // not specific enough,
    // because the function must return the same kind of monad, not just any monad
}

7

ওএর মধ্যে একটি মোনাদের "প্রাকৃতিক" ব্যাখ্যা রয়েছে কিনা তা মোনাডের উপর নির্ভর করে। জাভার মতো ভাষায়, আপনি সম্ভবত মনাডকে নাল পয়েন্টারগুলির জন্য পরীক্ষার ভাষায় অনুবাদ করতে পারেন, যাতে ফলশ্রুতি হিসাবে নকল পয়েন্টার নির্গমনকারী (যেমন, হাস্কেলের কোনও কিছুই উত্পাদন না করে) ব্যর্থ হয় ( পরিবর্তনীয় ভেরিয়েবল এবং এর রাষ্ট্র পরিবর্তন করার পদ্ধতি তৈরি করে আপনি রাজ্য মনাদকে উত্পন্ন ভাষায় অনুবাদ করতে পারেন।

একটি মোনাড হ'ল এন্ডোফান্টেক্টরগুলির বিভাগে একটি মায়োড।

বাক্যটি একসাথে যে তথ্য রাখে তা খুব গভীর। এবং আপনি কোনও অপরিহার্য ভাষা নিয়ে একটি মোনাডে কাজ করেন। একটি মোনাড একটি "সিকোয়েন্সড" ডোমেন নির্দিষ্ট ভাষা। এটি কিছু আকর্ষণীয় বৈশিষ্ট্যগুলিকে সন্তুষ্ট করে, যা একত্রে গ্রহণ করে "আবশ্যিক প্রোগ্রামিং" এর একটি গাণিতিক মডেল তৈরি করে। হাস্কেল ছোট (বা বড়) অপরিহার্য ভাষাগুলি সংজ্ঞায়িত করা সহজ করে তোলে, যা বিভিন্ন উপায়ে একত্রিত করা যায়।

ওও প্রোগ্রামার হিসাবে, আপনি আপনার ভাষার শ্রেণি শ্রেণিবিন্যাসকে বিভিন্ন প্রকারের ক্রিয়াকলাপ বা পদ্ধতিগুলি পরিচালনা করতে ব্যবহার করেন যা একটি প্রসঙ্গে বলা যেতে পারে, আপনি যাকে কোন বস্তু বলছেন। একটি মোনাডও এই ধারণার একটি বিমূর্ততা, ইনফার হিসাবে বিভিন্ন মনডকে যথেচ্ছ উপায়ে একত্রিত করা যেতে পারে, সাব-মোনাডের সমস্ত পদ্ধতিকে কার্যকরভাবে "আমদানি" করার সুযোগে।

আর্কিটেকচার্যালি, একের পর এক স্বাক্ষর করে স্বাক্ষর করে স্বাক্ষর করে কোন প্রসংগটি কোনও মান গণনা করার জন্য ব্যবহার করা যেতে পারে।

এই উদ্দেশ্যে কেউ মোনাড ট্রান্সফর্মার ব্যবহার করতে পারে এবং এখানে সমস্ত "স্ট্যান্ডার্ড" মনাদের একটি উচ্চ মানের সংগ্রহ রয়েছে:

  • তালিকা (ডোমেন হিসাবে একটি তালিকা চিকিত্সা করে অ-নিরস্তক গণনা)
  • হতে পারে (গণনা যা ব্যর্থ হতে পারে, তবে যার জন্য রিপোর্টিং গুরুত্বহীন)
  • ত্রুটি (গণনা যা ব্যর্থ হতে পারে এবং ব্যতিক্রম হ্যান্ডলিংয়ের প্রয়োজন
  • পাঠক (গণনা যা প্লেইন হাস্কেল ফাংশনগুলির রচনা দ্বারা প্রতিনিধিত্ব করা যেতে পারে)
  • লেখক (ক্রমিক "রেন্ডারিং" / "লগিং" (স্ট্রিংগুলিতে, এইচটিএমএল ইত্যাদির সাথে গণনা)
  • ধারাবাহিকতা (ধারাবাহিকতা)
  • আইও (অন্তর্নিহিত কম্পিউটার সিস্টেমের উপর নির্ভর করে এমন গণনা)
  • স্টেট (গণনা যার প্রসঙ্গে একটি সংশোধনযোগ্য মান রয়েছে)

সংশ্লিষ্ট মোনাড ট্রান্সফর্মার এবং টাইপ ক্লাস সহ। প্রকারের ক্লাসগুলি তাদের ইন্টারফেসগুলিকে একীকরণের মাধ্যমে মনডের সংমিশ্রণে পরিপূরক পদ্ধতির অনুমতি দেয়, যাতে কংক্রিট মনডগুলি মনাদ "ধরণের" জন্য মানক ইন্টারফেস প্রয়োগ করতে পারে। উদাহরণস্বরূপ, মডিউল কন্ট্রোল.মোনাদ.স্টেটে একটি শ্রেণি মোনাডস্টেট এসএম রয়েছে এবং (স্টেট গুলি) ফর্মের একটি উদাহরণ

instance MonadState s (State s) where
    put = ...
    get = ...

দীর্ঘ কাহিনীটি হ'ল একটি মোনাড হ'ল ফান্টেক্টর যা "প্রসঙ্গকে" একটি মানের সাথে সংযুক্ত করে, যার মনডে কোনও মান ইনজেকশনের উপায় রয়েছে এবং যার সাথে সংযুক্ত প্রসঙ্গের সাথে মানগুলি মূল্যায়নের উপায় রয়েছে, কমপক্ষে attached একটি সীমিত উপায়ে

তাই:

return :: a -> m a

এটি একটি ফাংশন যা টাইপ এ এর ​​মানকে এম টাইপের একটি মোনাদ "ক্রিয়া" তে ইনজেক্ট করে।

(>>=) :: m a -> (a -> m b) -> m b

এটি এমন একটি ফাংশন যা একটি মনোড অ্যাকশন গ্রহণ করে, তার ফলাফলটি মূল্যায়ন করে এবং ফলাফলটিতে একটি ফাংশন প্রয়োগ করে। (>> =) সম্পর্কে পরিষ্কার জিনিস হ'ল ফলাফলটি একই মনডে ad অন্য কথায়, এম >> = এফ, (>> =) এ ফলাফলটি এম এর বাইরে টেনে নিয়ে যায় এবং এটিকে চ এর সাথে আবদ্ধ করে রাখে, যাতে ফলাফলটি মনোদে থাকে is (বিকল্পভাবে, আমরা এটি বলতে পারি যে (>> =) এম এর মধ্যে এফ টান এবং এটি প্রয়োগ করে)) ফলস্বরূপ, যদি আমাদের f :: a -> এমবি, এবং জি :: বি -> এমসি থাকে তবে আমরা পারি "ক্রম" ক্রিয়া:

m >>= f >>= g

অথবা, "স্বরলিপি দিন" ব্যবহার করে

do x <- m
   y <- f x
   g y

(>>) এর ধরণটি আলোকিত হতে পারে। এটাই

(>>) :: m a -> m b -> m b

এটি সি এর মতো পদ্ধতিগত ভাষায় (;) অপারেটরের সাথে মিলে যায় এটি এটি স্বরলিপিটি দেয়:

m = do x <- someQuery
       someAction x
       theNextAction
       andSoOn

গাণিতিক এবং দার্শনিক যুক্তিতে, আমাদের ফ্রেম এবং মডেল রয়েছে, যা "স্বভাবতই" একাকীত্বের সাথে মডেল করা হয়। একটি ব্যাখ্যা একটি ফাংশন যা মডেলের ডোমেনটি সন্ধান করে এবং কোনও প্রস্তাবের (বা সূত্র, সাধারণীকরণের অধীনে) সত্য মানের (বা সাধারণীকরণ) গণনা করে। প্রয়োজনীয়তার একটি সাধারণ যুক্তিতে আমরা বলতে পারি যে "প্রতিটি সম্ভাব্য বিশ্বে" যদি সত্য হয় তবে প্রস্তাবটি প্রয়োজনীয় if যদি এটি প্রতিটি স্বীকৃত ডোমেনের ক্ষেত্রে সত্য হয়। এর অর্থ হ'ল প্রস্তাবের জন্য কোনও ভাষার মডেলকে এমন একটি মডেল হিসাবে সংশোধন করা যেতে পারে যার ডোমেন স্বতন্ত্র মডেলগুলির সংকলন নিয়ে গঠিত (প্রতিটি সম্ভাব্য বিশ্বের অনুরূপ একটি)। প্রতিটি মোনাডের "যোগ" নামক একটি পদ্ধতি রয়েছে যা স্তরগুলিকে ফ্ল্যাশ করে, যার দ্বারা বোঝা যায় যে প্রতিটি মোনাড ক্রিয়া যার ফলস্বরূপ একটি মোনাদ ক্রিয়া মোনাডে এমবেড করা যেতে পারে।

join :: m (m a) -> m a

আরও গুরুত্বপূর্ণ, এর অর্থ এটি যে মোনাদটি "স্তর স্ট্যাকিং" অপারেশনের অধীনে বন্ধ রয়েছে। মোনাড ট্রান্সফরমারগুলি এভাবেই কাজ করে: তারা এ জাতীয় প্রকারের জন্য "যোগদানের মতো" পদ্ধতি সরবরাহ করে মনাদগুলিকে একত্রিত করে

newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }

যাতে আমরা কার্যকরভাবে স্তরগুলিকে ভেঙে ফেলা (মায়ানটি মি) এর একটি ক্রিয়াকে মিটার ক্রিয়ায় রূপান্তর করতে পারি। এই ক্ষেত্রে, রানমেবেট :: মায়ানটি মা -> মি (সম্ভবত এ) আমাদের যোগ-মত পদ্ধতি। (মায়াটিটি এম) একটি মোনাড এবং মায়েনটি :: এম (হতে পারে একটি) -> মায়েনটি এম কার্যকরভাবে মি তে নতুন ধরণের মনোড ক্রিয়া তৈরির জন্য নির্মাতা।

ফ্যান্টেক্টরের জন্য একটি নিখরচায় মোনাড হ'ল এফ স্ট্যাকিং দ্বারা নির্মিত ম্যানড, এর সাথে এই বোঝা যায় যে চ জন্য প্রতিটি নির্মাণকারীর ক্রমগুলি মুক্ত মোনাডের একটি উপাদান (বা আরও সঠিকভাবে, যা নির্মাতাদের সিকোয়েন্স গাছের মতো একই আকারের সাথে থাকে) চ)। ফ্রি ম্যানড হ'ল ন্যূনতম পরিমাণে বয়লার-প্লেট সহ নমনীয় মনড তৈরির জন্য একটি দরকারী কৌশল। একটি হাস্কেল প্রোগ্রামে, আমি টাইপ সুরক্ষা বজায় রাখতে সহায়তা করার জন্য "উচ্চ স্তরের সিস্টেম প্রোগ্রামিং" এর জন্য সহজ ম্যানডগুলি সংজ্ঞায়িত করতে মুক্ত ম্যানড ব্যবহার করতে পারি (আমি কেবল ধরণের এবং তাদের ঘোষণাগুলি ব্যবহার করছি comb সংযোজকগুলির ব্যবহারের সাথে বাস্তবায়নগুলি সরাসরি এগিয়ে রয়েছে):

data RandomF r a = GetRandom (r -> a) deriving Functor
type Random r a = Free (RandomF r) a


type RandomT m a = Random (m a) (m a) -- model randomness in a monad by computing random monad elements.
getRandom     :: Random r r
runRandomIO   :: Random r a -> IO a (use some kind of IO-based backend to run)
runRandomIO'  :: Random r a -> IO a (use some other kind of IO-based backend)
runRandomList :: Random r a -> [a]  (some kind of list-based backend (for pseudo-randoms))

মোনাডিজম হ'ল অন্তর্নিহিত আর্কিটেকচার যা আপনি "দোভাষী" বা "কমান্ড" প্যাটার্নটিকে কল্পনা করতে পারেন তার পরিষ্কার ফর্মের সাথে বিমূর্ত, যেহেতু প্রতিটি মনাদিক গণনা কমপক্ষে তুচ্ছভাবে "রান" করা উচিত। (রানটাইম সিস্টেমটি আমাদের জন্য আইও মনাদ চালায় এবং এটি যে কোনও হাস্কেল প্রোগ্রামের প্রবেশের পয়েন্ট I IO ক্রিয়াকলাপ চালিয়ে বাকী গণনাগুলি "ড্রাইভ" করে)।

যোগদানের ধরণটি এখানেও যেখানে আমরা বিবৃতিটি পাই যে একটি মোনাডটি এন্ডোফান্টরগুলির বিভাগে একঘেয়েমি। তাত্ত্বিক উদ্দেশ্যে, প্রকারভেদে যথাযথভাবে যোগ দেওয়া সাধারণত গুরুত্বপূর্ণ। তবে ধরণটি বোঝার অর্থ মনড বোঝা। যোগদান ও মোনাড ট্রান্সফর্মারের যোগ-মত প্রকারগুলি কার্যকারিতা রচনার অর্থে কার্যকরভাবে এন্ডোফানেক্টরগুলির রচনা। এটিকে হাস্কেলের মতো সিউডো-ভাষায় রাখতে,

ফুঃ :: মি (মা) <-> (মি। মি) ক


3

একটি মোনাড হ'ল ফাংশনগুলির একটি অ্যারে

(পিএসটি: ফাংশনগুলির একটি অ্যারে কেবল একটি গণনা)।

আসলে, সত্যিকারের অ্যারের পরিবর্তে (একটি সেল অ্যারেতে একটি ফাংশন) আপনার অন্য ফাংশন দ্বারা জড়িত সেগুলি রয়েছে >> =। >> = ফাংশন i + 1 ফাংশনটি ফিড i + 1 এ ফলাফলগুলি খাপ খাইয়ে নিতে, তাদের মধ্যে গণনা সম্পাদন করতে বা এমনকি ফাংশন i + 1 এ কল করতে নাও অনুমতি দেয়।

এখানে ব্যবহৃত প্রকারগুলি হ'ল "প্রসঙ্গের সাথে প্রকারের"। এটি একটি "ট্যাগ" সহ একটি মান। শৃঙ্খলাবদ্ধ থাকা ক্রিয়াকলাপগুলি অবশ্যই একটি "নগ্ন মান" নেবে এবং ট্যাগযুক্ত ফলাফলটি ফিরিয়ে আনবে। >> = এর একটি কর্তব্য হ'ল এর প্রসঙ্গের বাইরে একটি নগ্ন মান বের করা। "রিটার্ন" ফাংশনটিও রয়েছে, এটি একটি নগ্ন মান নেয় এবং একটি ট্যাগ দিয়ে রাখে।

সম্ভবত একটি উদাহরণ । আসুন এটি একটি সাধারণ পূর্ণসংখ্যা সঞ্চয় করতে ব্যবহার করুন যার উপরে গণনা করা যায়।

-- a * b
multiply :: Int -> Int -> Maybe Int
multiply a b = return  (a*b)

-- divideBy 5 100 = 100 / 5
divideBy :: Int -> Int -> Maybe Int
divideBy 0 _ = Nothing -- dividing by 0 gives NOTHING
divideBy denom num = return (quot num denom) -- quotient of num / denom

-- tagged value
val1 = Just 160 

-- array of functions feeded with val1
array1 = val1 >>= divideBy 2  >>= multiply 3 >>= divideBy  4 >>= multiply 3

-- array of funcionts created with the do notation
-- equals array1 but for the feeded val1
array2 :: Int -> Maybe Int
array2 n = do
       v <- divideBy 2  n
       v <- multiply 3 v
       v <- divideBy 4 v
       v <- multiply 3 v
       return v

-- array of functions, 
-- the first >>= performs 160 / 0, returning Nothing
-- the second >>= has to perform Nothing >>= multiply 3 ....
-- and simply returns Nothing without calling multiply 3 ....
array3 = val1 >>= divideBy 0  >>= multiply 3 >>= divideBy  4 >>= multiply 3

main = do
     print array1
     print (array2 160)
     print array3

সাহায্যকারী ক্রিয়াকলাপগুলির সাথে মনাদগুলি ফাংশনগুলির অ্যারে দেখানোর জন্য কেবল উপরের উদাহরণের সমতুল্য বিবেচনা করুন, কেবলমাত্র কার্যাদিগুলির প্রকৃত অ্যারে ব্যবহার করে

type MyMonad = [Int -> Maybe Int] -- my monad as a real array of functions

myArray1 = [divideBy 2, multiply 3, divideBy 4, multiply 3]

-- function for the machinery of executing each function i with the result provided by function i-1
runMyMonad :: Maybe Int -> MyMonad -> Maybe Int
runMyMonad val [] = val
runMyMonad Nothing _ = Nothing
runMyMonad (Just val) (f:fs) = runMyMonad (f val) fs

এবং এটি এটি ব্যবহার করা হবে:

print (runMyMonad (Just 160) myArray1)

1
সুপার-ঝরঝরে! সুতরাং বাঁধাই প্রসঙ্গের সাথে একটি ক্রিয়াকলাপ, প্রসঙ্গের সাথে একটি
ইনপুটটিতে

>>=একজন অপারেটর
ব্যবহারকারী 2418306

1
আমি মনে করি "ফাংশনগুলির অ্যারে" উপমাটি খুব বেশি স্পষ্ট করে না। যদি \x -> x >>= k >>= l >>= mফাংশনগুলির একটি অ্যারে হয়, তবে এটি হ'ল h . g . fযা মণাদগুলিকে মোটেই জড়িত না।
দ্বৈত

আমরা বলতে পারি যে ফান্ট্যাক্টরা , মোনাডিক, প্রয়োগমূলক বা প্লেইন, "শোভিত অ্যাপ্লিকেশন" সম্পর্কে । 'প্রয়োগকারী' শৃঙ্খলা যোগ করে এবং 'মোনাড' নির্ভরতা যুক্ত করে (অর্থাত্ পূর্ববর্তী গণনা পদক্ষেপের ফলাফলের উপর নির্ভর করে পরবর্তী গণনা পদক্ষেপ তৈরি করা)।
নেস

3

ওও শর্তাবলী, একটি monad একটি সাবলীল ধারক হয়।

সর্বনিম্ন প্রয়োজনীয়তা একটি সংজ্ঞা class <A> Somethingযা কোনও নির্মাণকারী Something(A a)এবং কমপক্ষে একটি পদ্ধতি সমর্থন করেSomething<B> flatMap(Function<A, Something<B>>)

তর্কযুক্তভাবে, এটিও গণনা করে যদি আপনার মোনাড শ্রেণিতে স্বাক্ষর সহ কোনও পদ্ধতি থাকে Something<B> work()যা শ্রেণীর বিধিগুলি সংরক্ষণ করে - সংকলনের সময় ফ্ল্যাটম্যাপে সংকলক বেক করে।

কেন একটি monad দরকারী? কারণ এটি এমন একটি ধারক যা চ্যানেল-সক্ষম অপারেশনগুলিকে অনুমতি দেয় যা শব্দার্থক সংরক্ষণ করে। উদাহরণস্বরূপ, Optional<?>জন্য isPresent এর শব্দার্থবিদ্যা অপরিবর্তিত Optional<String>, Optional<Integer>,Optional<MyClass> , ইত্যাদি

মোটামুটি উদাহরণ হিসাবে,

Something<Integer> i = new Something("a")
  .flatMap(doOneThing)
  .flatMap(doAnother)
  .flatMap(toInt)

নোট করুন আমরা একটি স্ট্রিং দিয়ে শুরু করব এবং পূর্ণসংখ্যা দিয়ে শেষ করব। বেশ দারুন.

ওওতে, এটি সামান্য হাত-দোলা নিতে পারে, তবে সামথিংয়ের যে কোনও পদ্ধতি যা সামথিংয়ের আরেকটি সাবক্লাস ফেরত দেয় এমন একটি ধারক ফাংশনের মানদণ্ডকে পূরণ করে যা মূল ধরণের একটি ধারক ফেরত দেয়।

আপনি কীভাবে শব্দার্থকতা সংরক্ষণ করেন - যেমন ধারকটির অর্থ এবং ক্রিয়াকলাপগুলি পরিবর্তন হয় না, তারা কেবল ধারকটির ভিতরে থাকা বস্তুটি মোড়ানো এবং বাড়িয়ে তোলে।


2

সাধারণ ব্যবহারের মধ্যে মনাদ হ'ল পদ্ধতিগত প্রোগ্রামিংয়ের ব্যতিক্রম হ্যান্ডলিং প্রক্রিয়াগুলির কার্যকরী সমতুল্য।

আধুনিক পদ্ধতিগত ভাষায়, আপনি বিবৃতিগুলির অনুক্রমের চারপাশে একটি ব্যতিক্রম হ্যান্ডলার রাখেন, যার যে কোনও একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে। যদি বিবৃতিগুলির মধ্যে কোনও ব্যতিক্রম ছুঁড়ে দেয়, তবে বিবৃতিগুলির ক্রমটির সাধারণ সম্পাদন বন্ধ হয়ে যায় এবং ব্যতিক্রম হ্যান্ডলারের কাছে স্থানান্তর হয়।

কার্যকরী প্রোগ্রামিং ল্যাঙ্গুয়েজগুলি যদিও, দার্শনিকভাবে তাদের প্রকৃতির মতো "গোটো" এর কারণে ব্যতিক্রম হ্যান্ডলিং বৈশিষ্ট্যগুলি এড়িয়ে যায়। কার্যকরী প্রোগ্রামিং দৃষ্টিভঙ্গি হ'ল ফাংশনগুলির ব্যতিক্রমগুলির মতো "পার্শ্ব-প্রতিক্রিয়া" থাকা উচিত নয় যা প্রোগ্রাম প্রবাহকে ব্যাহত করে।

বাস্তবে, মূলত I / O এর কারণে আসল বিশ্বে পার্শ্ব-প্রতিক্রিয়াগুলি অস্বীকার করা যায় না। ফাংশনাল প্রোগ্রামিংয়ের মনডগুলি চেইন ফাংশন কলগুলির সেট (যার মধ্যে যে কোনও অপ্রত্যাশিত ফলাফল হতে পারে) এবং কোনও অপ্রত্যাশিত ফলাফলকে এনক্যাপসুলেটেড ডেটাতে পরিণত করে এটি পরিচালনা করতে ব্যবহৃত হয় যা এখনও বাকী ফাংশন কলগুলির মাধ্যমে নিরাপদে প্রবাহিত হতে পারে।

নিয়ন্ত্রণের প্রবাহ সংরক্ষণ করা হয় তবে অপ্রত্যাশিত ইভেন্টটি নিরাপদে এনপ্যাপুলেটেড এবং পরিচালনা করা হয়।


2

মার্ভেলের কেস স্টাডি সহ একটি সাধারণ মনডাস ব্যাখ্যা এখানে

মনডস নির্ভরশীল ফাংশনগুলি কার্যকর করার জন্য ক্রম ব্যবহার করতে বিমূর্ততা ব্যবহার করে। কার্যকর এখানে অর্থ তারা F [A] ফর্মের একটি টাইপ ফেরত দেয় উদাহরণস্বরূপ বিকল্প [A] যেখানে বিকল্পটি এফ, টাইপ কনস্ট্রাক্টর বলে। আসুন এটি 2 সহজ পদক্ষেপে দেখুন

  1. নীচে ফাংশন রচনাটি ট্রানজিটিভ। সুতরাং এ থেকে সিআই এ যাওয়ার জন্য এ => বি এবং বি => সি রচনা করতে পারেন
 A => C   =   A => B  andThen  B => C

এখানে চিত্র বর্ণনা লিখুন

  1. যাইহোক, যদি ফাংশনটি অপশন [এ] অর্থাৎ এ => এফ [বি] এর মতো কোনও প্রকারের টাইপ দেয় তবে রচনাটি বি তে যাওয়ার মতো কাজ করে না আমাদের A => B প্রয়োজন তবে আমাদের কাছে A => F [B] রয়েছে।
    এখানে চিত্র বর্ণনা লিখুন

    আমাদের একটি বিশেষ অপারেটর দরকার, "বাঁধাই" যা জানে কীভাবে এই ফাংশনগুলি ফিউজ করতে হয় যা এফ [এ] ফেরত দেয়।

 A => F[C]   =   A => F[B]  bind  B => F[C]

"বেঁধে" ফাংশন নির্দিষ্ট জন্য সংজ্ঞায়িত করা হয় এফ

রয়েছে "আসতে" , টাইপ একটি => এফ [এক] কোন একজন , যে নির্দিষ্ট জন্য সংজ্ঞায়িত এফ এছাড়াও। মোনাড হতে, এফ এর অবশ্যই এই দুটি ফাংশন সংজ্ঞায়িত করা উচিত।

সুতরাং আমরা কোনও খাঁটি ফাংশন এ => বি থেকে কার্যকর ফাংশন এ => এফ [বি] তৈরি করতে পারি ,

 A => F[B]   =   A => B  andThen  return

তবে প্রদত্ত এফ এ জাতীয় ধরণের নিজস্ব অস্বচ্ছ "বিল্ট-ইন" বিশেষ ফাংশনগুলিও সংজ্ঞায়িত করতে পারে যা কোনও ব্যবহারকারী তাদেরকে নির্ধারণ করতে পারে না ( খাঁটি ভাষায়), যেমন

  • "এলোমেলো" ( রেঞ্জ => এলোমেলো [ইন্টারঅ্যাক্টিভ] )
  • "মুদ্রণ" ( স্ট্রিং => আইও [()] )
  • "চেষ্টা করুন ... ধরুন", ইত্যাদি

2

আমি মনাদদের সম্পর্কে আমার বোঝার অংশটি ভাগ করছি, যা তাত্ত্বিকভাবে নিখুঁত নাও হতে পারে। মনডস কনটেক্সট প্রচার সম্পর্কে । মোনাড হ'ল, আপনি কিছু ডেটা (বা ডেটা টাইপ (গুলি) এর জন্য কিছু প্রসঙ্গ নির্ধারণ করুন এবং তারপরে সংজ্ঞা দিন যে কীভাবে প্রসঙ্গটি তার প্রসেসিং পাইপলাইন জুড়ে ডেটা সহ বহন করবে। এবং প্রসঙ্গ প্রচারের সংজ্ঞা দেওয়া বেশিরভাগ ক্ষেত্রে কীভাবে একাধিক প্রসঙ্গে (একই ধরণের) মার্জ করা যায় তা নির্ধারণ করা about মোনাড ব্যবহারের অর্থ হ'ল দুর্ঘটনাক্রমে তথ্যগুলি থেকে এই বিষয়গুলি সরিয়ে ফেলা না হয় তা নিশ্চিত করা। অন্যদিকে, অন্যান্য প্রসঙ্গ-কম ডেটা একটি নতুন বা বিদ্যমান প্রেক্ষাপটে আনা যেতে পারে। তারপরে এই সাধারণ ধারণাটি কোনও প্রোগ্রামের সংকলনের সময় যথার্থতা নিশ্চিত করতে ব্যবহার করা যেতে পারে।


1

আপনি যদি কখনও পাওয়ারশেল ব্যবহার করেন তবে এরিক বর্ণিত প্যাটার্নগুলি পরিচিত হওয়া উচিত। পাওয়ারশেল সেমিডলেটগুলি হ'ল মনাদ; কার্যকরী রচনাটি পাইপলাইন দ্বারা প্রতিনিধিত্ব করা হয় ।

এরিক মেইজারের সাথে জেফরি স্নোভারের সাক্ষাত্কারটি আরও বিশদে যায়।


1

"একটি মোনাদ কী?" এ আমার উত্তর দেখুন ?

এটি একটি অনুপ্রেরণামূলক উদাহরণ দিয়ে শুরু হয়, উদাহরণের মাধ্যমে কাজ করে, একটি মনাদের উদাহরণ গ্রহণ করে এবং "মোনাড" আনুষ্ঠানিকভাবে সংজ্ঞায়িত করে।

এটি কার্যকরী প্রোগ্রামিংয়ের কোনও জ্ঞান ধরে না এবং এটি function(argument) := expressionসহজতম এক্সপ্রেশনগুলির সাথে সিনট্যাক্স সহ সিউডোকোড ব্যবহার করে।

এই সি ++ প্রোগ্রামটি সিউডোকোড মোনাডের একটি বাস্তবায়ন। (রেফারেন্সের জন্য: Mটাইপ কনস্ট্রাক্টর feedহ'ল "বাইন্ড" অপারেশন, এবং wrapএটি "রিটার্ন" অপারেশন))

#include <iostream>
#include <string>

template <class A> class M
{
public:
    A val;
    std::string messages;
};

template <class A, class B>
M<B> feed(M<B> (*f)(A), M<A> x)
{
    M<B> m = f(x.val);
    m.messages = x.messages + m.messages;
    return m;
}

template <class A>
M<A> wrap(A x)
{
    M<A> m;
    m.val = x;
    m.messages = "";
    return m;
}

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

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

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

int main()
{
    V x;
    M<T> m = feed(f, feed(g, wrap(x)));
    std::cout << m.messages;
}

0

ব্যবহারিক দৃষ্টিকোণ থেকে (অনেকগুলি পূর্ববর্তী উত্তর এবং সম্পর্কিত নিবন্ধগুলিতে যা বলা হয়েছে তার সংক্ষিপ্তসার), আমার কাছে মনে হয় যে মোনাডের অন্যতম মৌলিক "উদ্দেশ্য" (বা উপযোগ) হ'ল পুনরাবৃত্ত পদ্ধতিতে অনুরোধের উপর নির্ভরশীলতা অর্জন করা is অরফ ফাংশন কম্পোজিশন (যখন f1 কল এফ 3 কল এফ 3 এর আগে, F3 এর আগে F2 এর আগে F2 এর আগে মূল্যায়ন করা প্রয়োজন) বিশেষত একটি অলস মূল্যায়ন মডেলের প্রসঙ্গে (যা, সরল ক্রম হিসাবে ক্রমবর্ধমান রচনা) উদাহরণস্বরূপ, "এফ 3 (); এফ 2 (); এফ 1 ();" সি তে - কৌশলটি বিশেষত স্পষ্ট হয় যদি আপনি এমন কোনও ক্ষেত্রে ভাবেন যেখানে f3, f2 এবং f1 আসলে কিছুই ফিরিয়ে দেয় না [তাদের চেইনটি f1 (f2 (f3)) হিসাবে দেখায় কৃত্রিম, নিখুঁতভাবে ক্রম তৈরি করার উদ্দেশ্যে]]।

পার্শ্ব-প্রতিক্রিয়া জড়িত থাকাকালীন এটি বিশেষত প্রাসঙ্গিক, যেমন যখন কিছু রাজ্য পরিবর্তন করা হয় (যদি f1, f2, f3 এর কোনও পার্শ্ব-প্রতিক্রিয়া না থাকে, তবে তারা কীভাবে মূল্যায়ন করা হয় তা বিবেচ্য নয়; যা খাঁটি একটি দুর্দান্ত সম্পত্তি কার্যকরী ভাষা, উদাহরণস্বরূপ those গণনাগুলির সমান্তরাল করতে সক্ষম হতে। আরও খাঁটি ফাংশন, আরও ভাল।

আমি মনে করি এই সংকীর্ণ দৃষ্টিকোণ থেকে, মনাদগুলিকে অলস মূল্যায়নের পক্ষপাতী ভাষাগুলির সিনট্যাকটিক চিনি হিসাবে দেখা যেতে পারে (যে কোডটির উপস্থাপনার উপর নির্ভর করে না এমন আদেশ অনুসরণ করে, যখন একেবারে প্রয়োজনীয় তখন বিষয়গুলি মূল্যায়ন করে), এবং এর কোনও নেই অনুক্রমিক রচনা উপস্থাপনের অন্যান্য উপায়। নেট ফলাফলটি হ'ল "অপরিষ্কার" কোডের বিভাগগুলি (অর্থাত্ পার্শ্ব-প্রতিক্রিয়াগুলি রয়েছে) প্রাকৃতিকভাবে, একটি আবশ্যক পদ্ধতিতে উপস্থাপন করা যেতে পারে, তবুও পরিষ্কারভাবে খাঁটি ফাংশন থেকে পৃথক করা হয় (কোনও পার্শ্ব-প্রতিক্রিয়া ছাড়াই), যা হতে পারে অলসভাবে মূল্যায়ন।

এখানে যেমন সতর্ক করা হয়েছে এটি কেবলমাত্র একটি দিক ।


0

আমি যে সহজ ব্যাখ্যাটি ভাবতে পারি তা হ'ল মনাদগুলি শোভিত ফলাফলগুলি (ওরফে ক্লাইসলি রচনা) সহ ফাংশন রচনা করার একটি উপায়। একটি "embelished" ফাংশন স্বাক্ষর হয়েছে a -> (b, smth)যেখানে aএবং bপ্রকার (মনে হয় Int, Bool) যে একে অপরের থেকে ভিন্ন হতে পারে, কিন্তু অগত্যা - এবং smth"প্রসঙ্গ" বা "embelishment" হয়।

এই ধরনের ফাংশনগুলি a -> m bসেখানে লেখা যেতে পারে যেখানে m"শোভন" এর সমতুল্য smth। সুতরাং এগুলি ফাংশন যা প্রসঙ্গে মানগুলি ফেরত দেয় (তাদের ক্রিয়াগুলি লগ করে এমন ফাংশনগুলি ভাবেন, smthলগিং বার্তাটি কোথায় ; অথবা ফাংশনগুলি যা ইনপুট-আউটপুট সম্পাদন করে এবং তাদের ফলাফলগুলি আইও অ্যাকশনের ফলাফলের উপর নির্ভর করে)।

একটি মোনাড হ'ল একটি ইন্টারফেস ("টাইপক্লাস") যা প্রয়োগকারীকে এটি কীভাবে এই জাতীয় ফাংশনগুলি রচনা করতে হয় তা বলায়। প্রয়োগকারীকে যে (a -> m b) -> (b -> m c) -> (a -> m c)কোনও ধরণের mইন্টারফেস বাস্তবায়িত করতে চায় (এটি ক্লাইসলি রচনা) বাস্তবায়নের জন্য একটি রচনা ফাংশন সংজ্ঞায়িত করতে হবে।

সুতরাং, যদি আমরা বলি যে আমাদের কাছে একটি টুপল টাইপ রয়েছে (Int, String)যা গণনাগুলির ফলাফলকে উপস্থাপন করে Intযা তাদের ক্রিয়াকলাপগুলিকে (_, String)"উদ্বেগ" - অ্যাকশনের লগ - এবং দুটি ফাংশন সহ লগ করে increment :: Int -> (Int, String)এবং twoTimes :: Int -> (Int, String)আমরা একটি ফাংশন পেতে চাই incrementThenDouble :: Int -> (Int, String)যা রচনাটি দুটি ফাংশন যা লগগুলিকেও বিবেচনা করে।

প্রদত্ত উদাহরণে, দুটি ফাংশনের একটি মোনাড প্রয়োগের পূর্ণসংখ্যা মান 2 incrementThenDouble 2(যা সমান twoTimes (increment 2)) এর ক্ষেত্রে প্রযোজ্য (6, " Adding 1. Doubling 3.")মধ্যস্থতার ফলাফলের increment 2সমান (3, " Adding 1.")এবং twoTimes 3সমান হবে(6, " Doubling 3.")

এই ক্লাইসলি কম্পোজিশন ফাংশন থেকে একজন সাধারণ মনডিক ফাংশন অর্জন করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.