এই নিবন্ধটিতে এত বেশী কারিগরি পরিভাষা ব্যবহার করা হয়েছে যে হয়ত অধিকাংশ পাঠকের জন্য এটি বোঝা দুরূহ হতে পারে।(May 2019) |
ফাংশনাল প্রোগ্রামিং এ, মানাড হচ্ছে একটি ডিজাইন প্যাটার্ন[১] যেটা প্রোগ্রাম এর যৌক্তিকতার জন্য প্রয়োজনীয় অপরিবর্তনীয় বয়লারপ্লেট কোডগুলিকে স্বয়ংক্রিয়করণ করে এবং একটা প্রোগ্রামকে সাজাইতে জেনেরিকভাবে সহায়তা করে। মানাড তার নিজস্ব ডেটা টাইপ প্রবর্তনের মাধ্যমে এটি করে থাকে, যে ডেটা টাইপ কম্পুগণনার একটি নির্দিষ্ট রূপ প্রদর্শন করে, মানাডের অভ্যন্তরে যেকোন মৌলিক টাইপকে ঢেকে রাখার একটি কার্যপ্রণালী প্রদান করে (যেটি একটি মানাডিয় মান প্রদান করে), এবং মানাডিয় মান বের করার ফাংশন তৈরির একটি উপায় প্রদান করে (যেটাকে বলা হয় মানাডিয় ফাংশন)।[২]
এর দ্বারা মানাড একটি বৃহৎ পরিসর এর সমস্যার সমাধান করে, যেমন সম্ভাব্য অনির্দিষ্ট মানসমূহ নিয়ে কাজ করা (Maybe
মানাডের মাধ্যমে), অথবা মানসমূহকের একটি নমনীয় ও সুগঠিতভাবে তালিকাভুক্ত করা (List
মানাডের মাধ্যমে)। মানাডের সাহায্যে একজন প্রোগ্রামার একগাদা জটিল ফাংশনের একটা অনুক্রম কে একটা সংক্ষিপ্ত পাইপলাইনে পরিণত করতে পারে যেটা আনুষঙ্গিক ডেটা ব্যবস্থাপনা, প্রোগ্রাম নিয়ন্ত্রণ প্রবাহ(কন্ট্রোল ফ্লো) অথবা পার্শ্বপ্রতিক্রিয়া ইত্যাদিকে একটি বিমূর্তন(অ্যাবস্ট্রাকশন) এর পিছনে ফেলতে পারে।[২][৩]
মানাডের ধারণা এবং শাব্দিক উৎপত্তি উভয়ই ক্যাটাগরি তত্ত্ব হতে মূলত সৃষ্ট, যেখানে এটিকে বাড়তিভাবে গঠিত ফাঙ্কটর আখ্যা দেয়া হয়েছে।[ক] আশির দশকের শেষ দিকে ও নব্বুই দশকের শুরুর দিকে গবেষণার মাধ্যমে প্রমাণিত হয়ে যে, মানাডের সহায়তায় কম্পিউটার বিজ্ঞানের আপাতদৃষ্টিতে অসম সমস্যাগুলিকে একটি সমন্বিত ও ফাংশনাল মডেল এ উন্নীত করা সম্ভব। ক্যাটাগরি থিওরি কিছু আনুষ্ঠানিক রিকোয়ারমেন্ট প্রদান করে, যএটাকে মানাডিয় সূত্র হিসাবে অভিত করা যেতে পারে, যাকে যেকোন মানাড চরিতার্থ করতে পারে ও এগুলোর সাহায্যে মানাডিয় কোডসমূহকে যাচাই করা যেতে পারে[৪][৫]
যেহেতু মানাড কম্পুগণনার জন্য প্রয়োজনীয় সেমান্টিকস কে স্পষ্টভাবে বর্ণিত করে, সেহেতু মানাডের সাহায্যে কম্পিউটার ভাষার সুবিধাজনক সম্প্রসারণ সম্ভব। কিছু কম্পিউটার ভাষা, যেমন হাস্কেল, তাদের মূল লাইব্রেরিতে, মানাডের সাধারণ গঠন ও প্রচলিত নিদর্শনের জন্য পূর্ববর্ণিত সংজ্ঞা প্রদান করে।[২][৬]
"একটি মানাড m
এর জন্য, হরফ(টাইপ)m a
নির্দেশ করে, মানাডের প্রসঙ্গে, a
টাইপের মান ব্যবহারের ক্ষমতা" —সি. এ. ম্যাকান
মানাডের দ্বারা কেন ও কীভাবে প্রোগ্রাম করতে হবে তা একটি ছোট উদাহরণে প্রদত্ত স্যুডোকোডের সাহায্যে বোঝানো যায়। অনির্দিষ্ট মান ও ক্রিয়াপ্রণালী(অপারেশনস) হচ্ছে সফটওয়ার এর একটি বিশেষ সমস্যা, যেটাকে সৌষ্ঠবের সাথে মোকাবিলা করার জন্য প্রস্তত থাকলেই কেবলমাত্র সেই সফটওয়ার শক্তিশালী হিসেবে গৃহীত হবে।
এই উদ্দেশ্যে প্রথম করণীয় হচ্ছে একটি অপশনাল টাইপ তৈরি করা যা একটি নির্দিষ্ট গাণিতিক চলরাশিকে, কোন টাইপ T
(T
যে কোন টাইপ এর হতে পারে) এ মান বহন করছে কিনা তা চিন্থিত করবে। এই নতুন টাইপটিকে বলা হবে Maybe T
এবং এই টাইপটির মান হতে পারে হয় টাইপ T
অথবা শুন্যমান Nothing
। ধরি, Just X
হল টাইপ T
এর একটি মান X
যেটা পূর্বেই সংজ্ঞায়িত কিন্তু কেবলমাত্র Maybe
এর প্রসঙ্গে ব্যবহৃত হবে। এটি করার কারণ হল, চলরাশিটি কোন সংজ্ঞায়িত মান বহন করছে, কি করছে না, এই দুই ক্ষেত্রের মাঝে গোলমাল দুর করার জন্য।
data Maybe T = Just T or Nothing
Maybe T
কে "মোড়ক" টাইপ হিসেবে বিবেচনা করা যেতে পারে, যেটি টাইপ T
কে মুড়িয়ে বিল্ট-ইন এক্সেপশন হ্যান্ডলিং সমৃদ্ধ নতুন টাইপ এ পরিণত করে, যদিও সেটি এক্সেপশন এর কারণ সম্পর্কে কোন তথ্য বহন করে না।
নিম্নোক্ত কোডে, m
উপসর্গ যুক্ত চলরাশিগুলোর টাইপMaybe T
অথবা কেবলমাত্র টাইপ T
। উদাহরণস্বরূপ, যদি একটি চলরাশি mx
একটি মান বহন করে, তখন এটাকে Just x
হিসেবে চিন্থিত করা হবে, যেখানে চলরাশি x
এর টাইপ হচ্ছে T
। λx → ...
হচ্ছে একটি অজ্ঞাতনামা (অ্যানোনিমাস) ফাংশন যার প্যারামিটার হচ্ছে x
যার টাইপ অনুমিত (ইনফার্ড), এবং ∘
হচ্ছে ফাংশন সংযুতি (ফাংশন কম্পোজিশন) কার্যকারক (অপারেটর)।
আরেকটু উন্নতিসাধন করা যায়, যদি একটি ফাংশন, Maybe
টাইপের সাহায্যে চিন্থিত (চেকড) এক্সেপশনগুলো নিয়ন্ত্রণ করতে পারে, শর্ট-সার্কিট করতে পারে এবং যদি কোন ধাপ ব্যর্থ হয় তাহলে Nothing
ফেরত দিতে পারে, কিন্তু যখন একটি গণনা সফল হয় তখন সঠিক মান ফেরত দিতে পারে।
ঠিক এই কাজ করার জন্য একটি যোগাত্মক ফাংশন হল add
। দুটি Maybe
মান mx
ও my
এর যোগকে নিম্নোক্তভাবে সংজ্ঞায়িত করা যায়:
add : (Maybe Number, Maybe Number) → Maybe Number
add(mx,my) = ...
if mx is Nothing then
... Nothing
else if my is Nothing then
... Nothing
else
... Just (x + y)
end if
Maybe
এর মানগুলোকে এক একটি করে বোঝা কষ্টসাপেক্ষ, এবং যতই অধিক পরিমাণে ফাংশন সংজ্ঞায়িত হতে থাকবে ততই এটি আরও কষ্টসাপেক্ষ হতে থাকবে। এথেকে পরিত্রানের একটি উপায় হচ্ছে ধাপগুলোকে একত্রে শ্রেণীবদ্ধ করা। একটি নিষ্পাদন (ইনফিক্স) চালক (অপারেটর), যেমন x >>= y
, এর সাহায্যে সহজভাবে এক ধাপ হতে পরের ধাপে ফলাফলগুলি (যেটি অনির্দিষ্ট হবার সম্ভাবনা আছে) প্রেরণ প্রদর্শিত করা যেতে পারে। যদিও টেকনিক্যালি এক একটি রেজাল্ট আরেকটি ফাংশনে প্রেরণ করা হচ্ছে, তারপরও চালক (অপারেটর) প্যারামিটার হিসেবে আরেকটি ফাংশনকে গ্রহণ করবে। যেহেতু add
ইতিমধ্যে তার উত্পাদ (আউটপুট) এর টাইপ কে নির্দিষ্টায়িত করছে, সেহেতু এমন সব ফাংশন যাদের আউটপুট তাদের ইনপুট অপেক্ষা ভিন্ন, সেই সকল ফাংশনকে গ্রহণ করে অপারেটরকে নমনীয় রাখলে তা অপারেটরের জন্য সুবিধাজনকই হবে:
>>= : (Maybe T, T → Maybe U) → Maybe U
(mx >>= f) = ...
if mx is (Just x) then
... f(x) -- f returns a defined value of type Maybe U
else
... Nothing -- f returns no value
end if
যেহেতু >>=
ব্যবহারযোগ্য, add
কে আরও সংক্ষিপ্ত ও সংহতভাবে পুনরায় সংজ্ঞায়িত করা যেতে পারে:
add(mx,my) = mx >>= λx -> (my >>= λy -> Just (x + y))
এই সংজ্ঞাটি আরও সংক্ষিপ্ত, তবে আরও বিশ্লেষণের মাধ্যমে অধিকতর গুরুত্বপূর্ণ একটি জিনিস সম্বন্ধে ধারণা পাওয়া যেতে পারে। প্রথমত, অধীন মানগুলিকে আরও Maybe
মান হিসেবে সংজ্ঞায়িত করার জন্য add
এর কেবলমাত্র Just
ব্যবহার করা দরকার। Just
তার অধীন মানগুলোকে মুড়িয়ে (র্যাপিং করে) তাদের ওপর ক্রিয়াসাধন করে থাকে, সেটি সম্পর্কে জোর দিয়ে বলার জন্য, আমরা তাকে eta
নামক একটি ফাংশন হিসেবে পুনঃসংজ্ঞায়িত করি:
eta : T → Maybe T
eta(x) = Just x
এখানে লক্ষণীয় বিষয় যে, add
ফাংশনের সরলীকরণের জন্য এই দুটি ফাংশন >>=
এবং eta
তৈরি করা হলেও তারা add
এর কোন বৈশিষ্টের ওপর নির্ভর করে না, কেবলমমাত্র Maybe
টাইপের ওপরে নির্ভরশীল। এই ফাংশনগুলি Maybe
এর অধীন মানগুলির টাইপ নির্বিশেষে যেকোন মান ও ফাংশনের ওপর প্রযোজ্য হতে পারে। উদাহরণস্বরূপ, এখানে (ক্লীনের) ত্রৈধ যুক্তিবিদ্যা হতে একটি সংক্ষিপ্ত ঋণাত্মক চালক দেখানো হয়েছে যা অনির্দিষ্ট মানগুলির স্বয়ংক্রিয়করণের জন্য একই ফাংশনগুলি ব্যবহার করে:
trinot : Maybe Boolean → Maybe Boolean
trinot(mp) = mp >>= λp -> (eta ∘ not) p
বলা যায়, Maybe
টাইপ, >>=
এবং eta
এর সাথে যুক্ত হয়ে একটি মানাড গঠন করে। যদিও অন্য অনেক মানাড ভিন্ন ভিন্ন যুক্তিভিত্তিক প্রক্রিয়াকেে একত্র করে, এবং হয়ত অতিরিক্ত কিছু বৈশিষ্টকে ধারণ করে, তাদের সকলে এই উদাহরণের মূলনীতি অনুসরণ করে এই তিনটি উপাদানের সাহায্যে (প্রত্যক্ষ অথবা পরোক্ষভাবে) গঠিত হয়।[২][৭]
ফাংশনাল প্রোগ্রামিং এ মানাডের প্রচলিত সংজ্ঞা, যেটা উপোরক্ত উদাহারণে ব্যবহৃত হয়েছে, সেটি আসলে ক্যাটাগরি থিওরির সাধারণ সংজ্ঞার তুলনায় ক্লেইসি ত্রৈধ হতে উৎপন্ন হয়েছে। এই দুটি গঠন গাণিতিকভাবে সমতুল্য বলে প্রমাণিত হয়েছে, কারণ উভয় সংজ্ঞাই একটি বৈধ মানাড প্রদান করবে। যদি আমাদের নিকট কোন সুসংজ্ঞায়িত সাধারণ টাইপ T ও U থাকে, তাহলে একটি মানাড তিনটি অংশ নিয়ে গঠিত বলা যায়:
>>=
সাহায্যে প্রদর্শন করা যায়। যেটি একটি মানাডিক চলকের মোড়ক উন্মোচিত করে এবং তাকে একটি মানাডিক ফাংশনের/অভিব্যক্তির অভ্যন্তরে প্রবেশ করায়। যার কারণে নতুন মানাডিক মানের জন্ম হয়।তারপরও সম্পূর্ণভাবে মানাড হিসেবে পরিগণিত হতে উপর্যুক্ত তিনটি অংশের কিছু সূত্র মেনে চলতে হবে:
বীজগাণিতিকভাবে, এর অর্থ হচ্ছে, যে কোন মানাড দুটি জিনিসের জন্ম দেয়। মানাড একটি ক্যাটাগরির সূচনা করে (যাকে বলে ক্লেইসি ক্যাটাগরি) এবং, ফাঙ্কটর এর ক্যাটাগরির মাঝে একটি মনয়িড (মান হতে গণনা পর্যন্ত) এর সূচনা করে, যেটি একটি দ্বিমিক চালক(অপারেটর) ও unit(একক) এর সাহায্যে মানাডিয়ভাবে গঠিত হয়।[তথ্যসূত্র প্রয়োজন]
মানাড প্যাটার্ন এর ব্যবহার কেবলমাত্র কোড সংক্ষেপণ ও গাণিতিক যুক্তিপ্রয়োগের চাইতেও বহুদূরে বিস্তৃত। যে প্রোগ্রামিং ভাষা অথবা প্রচলিত প্যারাডাইম ই ব্যবহার করা হোক না কেন, মানাড প্যাটার্ন অনুসরণ করলে বিশুদ্ধ ফাংশনাল প্রোগ্রামিং এর অনেক সুবিধাই পাওয়া যায়। একটি নির্দিষ্ট প্রকার এর কম্পুগণনাকে বাস্তবায়ন (রেয়িফাই) করার মাধ্যমে একটি মানাড কম্পিউটেশনাল প্যাটার্ন এর বিরক্তিকর খুঁটিনাটি বেষ্টনীবদ্ধ (এনক্যাপসুলেট) করে এবং শুধু তাই নয়, এটি করে একটি ঘোষণামূলক উপায়ে করার মাধ্যমে কোডের স্পষ্টতা বৃদ্ধি করে। মানাডিক মান কেবলমাত্র নির্ণেয় মান প্রদর্শন করে না, তার সাথে সাথে নির্ণেয় প্রভাবকেও প্রকাশ করে থাকে। একটি মানাডিয় অভিব্যক্তির মানকে, বিশুদ্ধ অভিব্যক্তির ন্যায়, এর প্রাসঙ্গিক স্বচ্ছপদ দ্বারা প্রতিস্থাপন করা সম্ভব। এই সকল উপায়ে পুনর্লিখনের ওপর ভিত্তি করে নানা রকম কলাকৌশল প্রয়োগ ও দক্ষতা বৃদ্ধি করা যেতে পারে।[৫]
সাধারনত, প্রোগ্রামাররা bind (বাধাঁই) ব্যবহার করে অনেকগুলি মানাডিয় ফাংশনের একটি অনুক্রম তৈরি করে, যার কারণে "প্রোগ্রামযোগ্য সেমিকোলন" হিসেবে মানাড পরিচিতি পেয়েছে, প্রসঙ্গত, অনেক অনুজ্ঞাসূচক (ইম্পারেটিভ) প্রোগ্রামিং ভাষা সেমিকোলনের সাহায্যে এজাহার (স্টেটমেন্ট) গুলি জোড়া দেয়।[২][৬] তা সত্ত্বেও, এটা বলা গুরুত্বপূর্ণ যে, মানাড কখনও গণনার ক্রম পরিবর্তন করে না, এমনকি যেসকল প্রোগ্রামিং ভাষায় মানাড মুখ্য বৈশিষ্ট হিসেবে ব্যবহৃত হয় সেগুলোতেও; ফাংশনের সহজতর সংযুতি (কম্পোজিশন) প্রোগ্রামের ধাপগুলিকে ভেতর থেকে বিন্যস্ত করে। মানাডের প্রধান ব্যবহার হল প্রোগ্রামের কাঠামো সরলীকরণ এবং বিমূর্তনের (অ্যাবস্ট্রাকশন) মাধ্যমে সংস্রব পৃথকীকরণ।[৫][৯]
মানাডের কাঠামোকে একটি স্বতন্ত্র গাণিতিক ও প্রসাধক (ডেকোরেটর) প্যাটার্নের কম্পাইল করার সময়ের প্রকরণ হিসেবে দেখা যেতে পারে। কিছু কিছু মানাড বাড়তি ডেটা বহন করতে পারে যেটি ফাংশন দ্বারা উপলব্ধ নয়, আবার কিছু মানাড প্রোগ্রাম সম্পাদনের ওপর নিখুঁত প্রভাব বিস্তার করতে পারে। যেমন শর্তসাপেক্ষে ফাংশন সম্পাদন শুরু করা। যেহেতু মানাড অ্যাপ্লিকেশন প্রোগ্রামারদের ডোমেন লজিক বাস্তবায়ন করার সময় পূর্বে প্রস্তত করা মডিউলগুলোর মধ্যে বয়লারপ্লেট (গতবাধা) কোড খালাস করার ক্ষমতা প্রদান করে, তাই মানাডকে চেহারা-ভিত্তিক প্রোগ্রামিং এর একটি সরঞ্জাম হিসেবে বিবেচনা করা যেতে পারে।[১০]
মানাডের আরেকটি গুরুত্বপূ্র্ণ ব্যবহার হল ফাংশনাল কোডের বিশুদ্ধতা বজায় রাখতে পার্শ্বপ্রতিক্রিয়াগুলোকে আলাদা করা, যেমন ইনপুট/আউটপুট কিংবা পরিবর্তনযোগ্য অবস্থা (স্টেট)। বিশুদ্ধ ফাংশনাল ভাষাগুলিও এই সকল "অশুদ্ধ" পরিগণনা মানাডের সাহায্য ছাড়া (বিশেষভাবে) ফাংশন রচনা ও কন্টিনিউয়েশন-পাসিং স্টাইল (সিপিএস) এর একটি জটিল সংমিশ্রণের সাহায্যে সাহায্যে সম্পাদন করতে পারে।[৩] তবে মানাডের সাহায্যে এই সকল সমর্থন কাঠামোর বিমূর্তকরণ সম্ভব, মূলত, সিপিএস কোডে পাওয়া পুনরাবৃত্ত হওয়া প্রত্যেকটি প্যাটার্ন নিয়ে পৃৃথক পৃথক মানাডে বস্তাবন্দী করা।[৫]
যদি একটি প্রোগ্রামিং ভাষা মানাডের সমর্থন না দেয়, তাহলেও সেখানে খুব বেশি একটা অসুবিধা ছাড়াই মানাড প্যাটার্ন বাস্তবায়ন করা সম্ভব। ক্যাটাগরি -তত্ত্ব হতে প্রোগ্রামিং পরিভাষায় অনুবাদের সময় মানাডের গঠন একটা বর্গীয় ধারণা হিসেবে পরিগণিত হয় এবং কেবলমাত্র আবদ্ধ বহুরূপতার সমতু্ল্য বৈশিষ্ট সমর্থন করে এরকম একটি (প্রোগ্রামিং) ভাষায় সেটি সরাসরি সংজ্ঞায়িত করা সম্ভব। প্রায়োগিক খুঁটিনাটি সম্পর্কে জানা ছাড়াই একটি ধারণার অধীন টাইপের সাথে কাজ করার ক্ষমতা গুরুত্বপূর্ণ হিসেবে বিবেচিত হয়। কিন্তু মানাডের অনন্য বৈশিষ্টসমূহ এবং নিখুঁত আচরণ অন্যান্য ধ্যান-ধারণা হতে তাকে আলাদা করেছে।[১১]
নির্দিষ্ট কিছু মানাড নিয়ে আলোচনায় সাধারণত সীমিত আকারে প্রায়োগিক সমস্যা সমাধানের ওপর নজর দেয়া হয়, কারণ, একটি নির্দিষ্ট মানাড একটি নির্দিষ্ট কম্পিউটেশনাল ব্যবস্থাকে নির্দেশিত করে। যদিও কিছু কিছু ক্ষেত্রে একটি অ্যাপ্লিকেশন তার উচ্চমাত্রার লক্ষ্য সাধনে অন্তঃসার যুক্তিতে মানাডের ব্যবহার করতে পারে।
এখানে কিছু প্রয়োগ দেখানো হয়েছে যাদের তৈরিতে মানাডের ব্যবহার করা হয়েছে :
প্রোগ্রামিং এ "মানাড" শব্দটির ব্যবহার পিছনে ফিরে তাকালে সবার আগে এপিএল ও জে প্রোগ্রামিং ভাষায় পাওয়া যায়, যেগুলি বিশুদ্ধরূপে ফাংশনাল হিসেবে পরিচিত। তা সত্ত্বেও এই সকল ভাষায় "মানাড" একটি এক প্যারামিটার বিশিষ্ট ফাংশনের সংক্ষেপণ হিসেবে পরিচিত। (দুই প্যারামিটার বিশিষ্ট ফাংশনকে "ডায়াড" হিসেবে অভিহিত করা হয় ইত্যাদি)[১৫]
১৯৫০ এর দশকে, গণিতবিদ রজার গডেমেন্ড সর্বপ্রথম মানাডের ধারণা সূত্রবদ্ধ করেন (তিনি এটিকে "আদর্শ গঠন" বলে অভিহিত করেন), তবে, ক্য়াটাগরি তত্ত্ববাদী স্য়ান্ডার্স ম্য়াকলেনের কল্য়ানে "মানাড" পরিভাষাটি আধিপত্য় বিস্তার করে।[তথ্যসূত্র প্রয়োজন] ১৯৬৫ সালে গণিতবিদ হেইনরিখ ক্লেইসি সর্বপ্রথম, উপরে bind এর সাহায্যে যে নমুনাটি দেখানো হয়েছে, সেটির মাধ্যমে প্রমাণ করেন যে, একটি মানাডকে দুটি (কো-ভ্য়ারিয়েন্ট) ফাঙ্কটর এর সমষ্টি (অ্য়াডজাঙ্কশন) হিসেবে প্রকাশ করা যেতে পারে।[১৬]
১৯৮০র দশকের শুরুতে মানাড প্যাটার্ন এর একটা ভাসা-ভাসা ধারণা কম্পুবিজ্ঞানীদের মাঝে বিস্তার লাভ করতে শুরু করে। প্রোগ্রামিং ভাষাবিদ ফিলিপ ওয়াডলারের মতে, কম্পুবিজ্ঞানী জন সি রেনল্ডস ১৯৭০এর দশক ও ৮০'র দশকের শুরুতে মানাডের কিছু অংশবিশেষ সম্পর্কে অনুমান করতে পরেছিলেন, যখন তিনি ধারাবাহিক ক্ষেপণ নীতির (continuation-passing style) গুরুত্ব অনুধাবন করতে পেরেছিলেন, যখন তিনি নিয়মমাফিক সেমান্টিক এর একটি গুরুত্বপূর্ণ উৎস হিসেবে ক্যাটাগরি থিওরির গুরুত্ব অনুধাবন করতে পেরেছিলেন, এবং, যখন তিনি মান ও গণনার মাঝে টাইপের পার্থক্য নির্ণয় করতে পেরেছিলেন।[৫] গবেষণাকেন্দ্রীক ভাষা ওপাল যেটি ১৯৯০ সালের আগ পর্যন্ত সক্রিয়ভাবে ডিজাইন করা হচ্ছিল, সফলতার সাথে কানাডীয় টাইপের ওপর ভিত্তি করে ইনপুট/আউটপুট এর নকশা করছিল, কিন্তু এই সংলগ্নতা তখন অনুধাবন করা যায় নি।[১৭]
কম্পুবিজ্ঞানী ইউজিনিও মগ্গি ১৯৮৯ সালে একটি কনফারেন্স পেপারে সর্বপ্রথম ক্যাটাগরি থিওরির মানাডের সাথে ফাংশনাল প্রোগ্রামিং এর যোগসূত্র স্পষ্টভাবে স্থাপন করেন[১৮] এবং ১৯৯১ সালে এটির পরশোধিত অনুবর্তী একটি জার্নাল উপস্থাপন প্রকাশ করেন। পূর্বেকার গবেষণায়, কয়েকজন কম্পুবিজ্ঞানী ক্যাটাগরি থিওরির সাহায্য়ে ল্যাম্বডা ক্য়ালকুলাস এর সেমান্টিকস প্রদানে সফলতা লাভ করেন। মগ্গির গুরুত্বপূর্ণ আবিষ্কার ছিল এই যে, একটি বাস্তব জগতের প্রোগ্রাম, এক মান থেকে অন্য় মান তৈরির কোন ফাংশন নয়, বরঞ্চ একটি রুপান্তর (ট্রান্সফরমেশন) যেটি ঐ সকল মানসমূহের মধ্যে কম্পুগণনা করতে সাহায্য় করে। ক্য়াটাগরি থিওরির পরিভাষায় সাজালে, সিদ্ধান্ত নেয়া যায় যে, মানাড হচ্ছে এই সকল কম্পুগণনার প্রতিরূপী গাঠনিক প্রণালী।[৪]
আরও কয়েকজন এই ধারণার জনপ্রিয়করণ ও পরিবর্ধণ করেন, যাদেঁর মাঝে ছিলেন ফিলিপ ওয়াডলার এবং সাইমন পেয়টন জোনস যাঁরা, হাস্কেল এর স্পেসিফিকেশনের সাথে জড়িত ছিলেন। বিশেষত, হাস্কেল ভার্সন ১.২ পর্যন্ত ইনপুট/আউটপুট কে অলস মুল্য়ায়ন (লেজি ইভালুয়েশন) এর সাথে খাপ খাওয়ানোর জন্য় একটি "অলস (লেজি) স্ট্রিম" মডেল ব্য়বহার করছিল ব্য়বহার করছিল যেটি ছিল ঝামেলাকর। পরবর্তীতে হাস্কেল আরও নমনীয় মানাডিয় ইন্টারফেস গ্রহণ করে।[১৯] পরবর্তীতে হাস্কেল সম্প্রদায় ফাংশনাল প্রোগ্রামিং এর অন্য়ান্য় অনেক সমস্য়ায় মানাডের প্রয়োগ করেন এবং হাস্কেল ব্য়বহারকারী গবেষকরা সময়ের সাথে সাথে মানাডের প্য়াটার্ন বিভিন্ন আকারের গঠনপ্রণালীতে প্রয়োগ করে থাকেন যার মধ্য়ে ছিল অ্য়াপ্লিকেটিভ ফাঙ্কটর ও তীর (অ্য়ারো)।[তথ্যসূত্র প্রয়োজন]
প্রথম দিকে মানাডের সাহায্যে প্রোগ্রামিং শুধুমাত্র হাস্কেল ও এর উপজাত ভাষার মধ্যে সীমাবদ্ধ ছিল, কিন্তু পরবর্তীতে ফাংশনাল প্রোগ্রামিং অন্যান্য প্যারাডাইম কে প্রভাবিত করার সাথে সাথে অনেক প্রোগ্রামিং ভাষা মানাড প্যাটার্ন (নামে না হলেও মূলনীতি) গ্রহণ করেছে । বর্তমানে স্কিম, পার্ল, পাইথন, র্যাকেট, ক্লোজার, স্কালা, এফ# মানাড প্রস্তুতপ্রণালী রয়েছে। এছাড়া এমএল এ প্রমাণ হিসেবে অর্ন্তভুক্তি বিবেচনাধীন আছে।[তথ্যসূত্র প্রয়োজন]
মানাড ব্যবহার একটি সুবিধা হল প্রোগ্রামিং যুক্তির মাঝে গাণিতিক নির্ভুলতা আনা। মানাডিয় সূত্রের মাধ্যমে কেবলমাত্র একটি নিদর্শনের সঠিকতা নির্দেশই নয় বরঞ্চ সাবটাইপিং এর সাহায্যে আরও বিভিন্ন সংশ্লিষ্ট গঠনপ্রণালী (যেমন ফাঙ্কটর) হতে নিভিন্ন উপাদান ব্যবহার করা সম্ভব।
Maybe
উদাহারণটিতে ফেরত গেলে দেখা যাবে, এখানে Maybe
এর উপাদানগুলি মানাড তৈরি করার জন্য ঘোষিত, কিন্তু এগুলি মানাডিয় সূত্রসমূহ অনুমোদন করে কি না তা দেখার জন্য কোন প্রমাণ দেয়া হয় নি।
এটি শোধরানোর জন্য সাধারণ সূত্রগুলোর এক পার্শ্বে Maybe
এর উপাদানগুলোর যথাযথ বর্ণনা প্রবেশ করিয়ে, বীজগাণিতিকভাবে অসমতার একটি ধারা তৈরি করে অপর পার্শ্বে পৌছানোর চেষ্টা করা যেতে পারে:
সূত্র ১: eta(a) >>= f(x) ⇔ (Just a) >>= f(x) ⇔ f(a)
সূত্র ২: ma >>= eta(x) ⇔ ma if ma is (Just a) then eta(a) ⇔ Just a else or Nothing ⇔ Nothing end if
সূত্র ৩: (ma >>= f(x)) >>= g(y) ⇔ ma >>= (f(x) >>= g(y)) if (ma >>= f(x)) is (Just b) then if ma is (Just a) then g( ma >>= f(x) ) (f(x) >>= g(y)) a else else Nothing Nothing end if end if ⇔ if ma is (Just a) and f(a) is (Just b) then (g ∘ f) a else if ma is (Just a) and f(a) is Nothing then Nothing else Nothing end if
কম্পুবিজ্ঞানে বিরল হলেও, ক্যাটাগরি তত্ত্ব সরাসরি ব্যবহার করে, একটি মানাডকে দুইটি অতিরিক্ত স্বাভাবিক রুপান্তর (ন্য়াচারাল ট্রান্সফরমেশন) সংযুক্ত একটি ফাঙ্কটর হিসেবে কল্পনা করা যেতে পারে। প্রারম্ভিক গঠনপ্রণালীতে দরকার ম্য়াপ নামক একটি উচ্চ পর্যায়ের ফাংশন (অথবা "ফাংশনাল") যেটিকে ফাঙ্কটর হিসেবে গণনা করা যেতে পারে।
এটি সর্বদা কোন গুরুত্বপূর্ণ সমস্যা হয়ে দাড়ায় না, বিশেষত যদি পূর্বে-বিদ্যমান কোন ফাঙ্কটর থেকে মানাড উৎপাদন করা হয়, সেক্ষেত্রে মানাড স্বয়ংক্রিয়ভাবে map উত্তরাধিকার সূত্রে লাভ করে। (ঐতিহাসিক কারণে হাস্কেলে, এই map
কে fmap
বলা হয়।)
একটি মানাডের প্রথম রুপান্তর মূলত ক্লেইসি ত্রৈধ হতে প্রাপ্ত unit এর সমান, যেখানে কাঠামোগত শ্রেণিবিভাগ নিবিড়ভাবে অনুসরণ করা হয়, প্রতিপাদিত হয় যে, উক্ত unit প্রায়োগিক ফাঙ্কটরের বৈশিষ্ট বহন করে, যেটি একটি সাধারণ ফাঙ্কটর এবং একটি মানাড এর অন্তর্বর্তী গঠন হিসেবে কাজ করে। প্রায়োগিক প্রসঙ্গে (কনটেক্সট), unit কে কিছু ক্ষেত্রে বিশুদ্ধ ফাংশন হিসেবে উল্লেখ করা হয় কিন্তু তা আসলে একই ফাংশন। এইভাবে মানাড উৎপাদনে যে ধাপটি আলাদা সেটি হল, এখানে unitকে যে সূত্র সিদ্ধ করতে হবে; যেহেতু bind অসংজ্ঞায়িত, map এর মাধ্যমে সীমাটি প্রদান করা হয়েছে:
প্রায়োগিক ফাঙ্কটর হতে মানাড প্রাপ্তির শেষ ধাপে সংযুক্তি ফাংশন(ক্যাটাগরি থিওরিতে এটি একটি স্বাভাবিক রুপান্তর যেটিকে μ বলে প্রকাশ করা হয়) কার্যকর করার সময় দ্বিতীয়বার রুপান্তর ঘটে যেটি মানাডের অধীনস্থ ক্ষমতাগুলোকে "চ্যাপ্টা" করে (সমান করে) দেয়:
চারিত্রিক ফাংশন হিসেবে, join কে মানাডীয় সূত্রসমূহের তিনটি প্রকরণ সিদ্ধ করতে হবে:[তথ্যসূত্র প্রয়োজন]
একজন ডেভেলপার সরাসরি মানাড অথবা একটি ক্লেইসি ত্রৈধ যাই সংজ্ঞায়িত করুক না কেন, অধীনস্থ কাঠামো একই থাকবে এবং উভয়কে একে অপরের বিন্যাস থেকে উদ্ভাবন করা যাবে:
সহজতর ফাঙ্কটর থেকে কীভাবে একটি মানাড আহরণ করা যায় এবং সেটি আমাদের কীভাবে কাজে আসতে পারে সেটি তালিকা মানাড আমাদের প্রদর্শন করে। কিছু কিছু প্রোগ্রামিং ভাষায় তালিকার ন্যায় একটি ডেটা স্ট্রাকচার পূর্ব নির্ধারিত-ভাবে কিছু মৌলিক বৈশিষ্ট সংবলিত হয়ে আসে তাই, ধরি, একটি List
টাইপ কনসস্ট্রাকটর এবং append (শেষে জুড়ে দেয়া) অপারেটর (যেটিকে ++
ইনফিক্স প্রতীক দ্বারা সংজ্ঞায়িত করা হয়েছে) পূর্ব হতে প্রদত্ত।
তালিকার মাঝে একটি সরল মানকে স্থাপন করা বেশিরভাগ প্রোগ্রামিং ভাষার কাছে একটি মামুলি ব্যাপার। :
unit(x) = [x]
এদিক দিয়ে দেখলে, লিস্ট (তালিকা) কম্প্রিহেনসন এর সাথে একটি ফাংশন ক্রমান্বয়ে (ইটারেটিভ ভাবে) প্রয়োগ করাটা এবং তালিকাগুলোকে পূর্ণ মানাডে রুপান্তরিত করে ফেলাটা bind এর পক্ষে একটা সহজ বিকল্প হিসেবে প্রতীয়মান হতে পারে। এই পদ্ধতির অসুবিধা হল, bind মানাডিয় ফাংশনের প্রত্যাশা করে যা এক্ষেত্রে নিজেই তালিকা আউটপুট হিসেবে প্রদান করে। যত বেশি ফাংশন প্রয়োগ করা হবে, তালিকার ভেতরে তত বেশি তালিকার স্তর জমা হতে থাকবে, এবং সেক্ষেত্রে সাধারণ কম্প্রিহেনসন এর চাইতে বেশি কিছুর প্রয়োজন পড়বে।
তবে, পুরো তালিকার ওপর কোন একটি সাধারণ ফাংশন প্রয়োগের প্রক্রিয়া, অন্য কথায় map ব্যবহার করা তুলনামূলক সহজ:
(map φ) xlist = [ φ(x1), φ(x2), ..., φ(xn) ]
এখন, এই দুই প্রক্রিয়া List
কে প্রায়োগিক ফাঙ্কটরে রুপান্তরিত করে। মানাড হিসেবে পুরোপুরি গৃহীত হতে গেলে, পুনরাবৃত্তভাবে গঠিত বস্তুকে চ্যাপ্টা (Flatten) করার জন্য কেবলমাত্র join এর সুস্পষ্ট ব্যাখ্যা দেয়া প্রয়োজন, কিন্তু তালিকার জন্য কেবলমাত্র বাহিরের তালিকাকে বিকিয়ে ভেতরের যেগুলোর মধ্যে জিনিস আছে তাদেরকে জোড়া লাগানোর দরকার:
join(xlistlist) = join([xlist1, xlist2, ..., xlistn]) = xlist1 ++ xlist2 ++ ... ++ xlistn
এর ফলাফলে যে মানাডের সৃষ্টি হয় সেটি একটি তালিকা, এছাড়াও ফাংশনের প্রয়োগে এটি স্বয়ংক্রিয়ভাবে আকার পরিবর্তন এবং সংকোচন করে। এখন কেবলমাত্র একটি সমীকরণের সাহায্যে bind কে আহরণ করা সম্ভব, এবং এরপর মানাডিয় ফাংশনের একটি পাইপলাইনের মাধ্যমে List
এর মানসমূহকে ইনপুট হিসেবে গ্রহণ করা সম্ভব:
(xlist >>= f) = join ∘ (map f) xlist
মানাডিয় তালিকার একটি ব্যবহার হল, অনির্ণেয় কম্পুগণনাকে প্রদর্শন করা। List
অ্যালগোরিদমের প্রতিটি নির্বাহী সন্ধিক্ষণের মানকে ধারণ করে রাখতে সক্ষম, এবং পরবর্তীতে নিজেকে প্রতিটি ধাপে সংকোচন করে কোন কোন ধাপ কোন কোন ফলাফলের সৃষ্টি করে সেগুলি সম্পর্কে বিস্মৃত হতে পারক্ষম (যেটি নির্ণায়ক, সামগ্রিক অ্যালগোরিদমদের থেকে ক্ষেত্রবিশেষে নিজেকে আলাদা করে)। আরেকটি সুবিধা হচ্ছে, মানাডের মধ্যে check (অধীক্ষা) স্থাপন করা সম্ভব। প্রথমবার অকৃতকার্য হবার সময় থেকেই স্বচ্ছভাবে প্রোগ্রামের নির্দিষ্ট গতিপথ ছেটে ফেলা সম্ভব এবং এতে করে পাইপলাইনের ফাংশনগুলি পুনর্লিখনের প্রয়োজন পড়ে না। [২১]
দ্বিতীয় যে পরিস্থিতিতে List
লক্ষণীয় হয় সেটি হল, বহুমানবিশিষ্ট ফাংশন রচনা করার ক্ষেত্রে। উদাহরণস্বরূপ, কোন সংখ্যার n-তম জটিল মূল নির্ণয়ের ক্ষেত্রে, nটি অনন্য জটিল সংখ্যা পাওয়া যাবার কথা, কিন্তু যদি সেই ফলাফলের আরেকটি m-তম মূল নেয়া হয়, তাহলে চূড়ান্ত m•n এর মান m•n-তম মূলের মানের সমান হবে। List
, প্রতিটি পদক্ষেপের ফলাফল একটি গাণিতিকভাবে সঠিক ফ্ল্যাট তালিকায় সংকোচনের মাধ্যমে সম্পূর্ণ স্বয়ংক্রিয়ভাবে এই সমস্যার এই সমস্যার সমাধান করে।[২২]
প্রোগ্রামের যুক্তিগুচ্ছকে সাজানো ছাড়াও মানাড আরও অনেক কৌতূহলোদ্দীপক কলাকৌশলের সু্যোগ সৃষ্টি করে। মানাড বদরকারি বিভিন্ন অন্বিত (সিন্টাকটিক) বৈশিষ্ট্যের ভিত্তিপ্রস্তর স্থাপন করে। এ-ই সকল প্রোগ্রামিং ফিচার তৈরি করেও তারা তাদের উচ্চস্তরের এবং গাণিতিক প্রকৃতির কারণে গুরুত্বপূর্ণ অ্যাবস্ট্রাকশন (বিমূর্তণ) তৈরি করতে সক্ষম হয়।
যদিও bind খোলামেলাভাবে ব্যবহার করা যেতে পারে, কিন্তু অনেক প্রোগ্রামারগণ অনুজ্ঞাসূচক বিবৃতির অনুকরণে বাক্যগঠন পছন্দ করেন (এদেরকে হাস্কেলে do-notation/do-প্রতীকগুচ্ছ, ওক্যামেলে perform-notation, এফ# এ গাণিতিক-অভিব্যক্তি, স্কালাতে for-কম্প্রিহেনশন বলা হয়ে থাকে)। একটি মানাডিয় পাইপলাইনকে কোডব্লকের ছদ্মবেশ দেয়ার জন্য এটি সিন্ট্যাকটিক সুগার হিসেবে কাজ করে।
Maybe
এর মধ্যে থাকা add
ফাংশনটিকে হাস্কেলে অনুবাদ করলে এই বৈশিষ্টটির কার্যকারিতা সম্পর্কে আমরা ধারণা পেতে পারি। হাস্কেলে add
এর অ-মানাডিয় সংষ্করণটিকে এরকম দেখায়:
add mx my =
case mx of
Nothing -> Nothing
Just x -> case my of
Nothing -> Nothing
Just y -> Just (x + y)
মানাডিয় হাস্কেলে unit এর চলিত পরিভাষা return
, অধিকন্তু লাম্বডা অভিব্যক্তিগুলো ব্যবহার করার সময় বিশদভাবে উল্লেখ করা প্রয়োজন, কিন্তু তা সত্ত্বেও স্পষ্টতঃ, Maybe
মানাড একটি পরিষ্কারভাবে বর্ণিত সংজ্ঞার জন্ম দেয়।:
add mx my =
mx >>= (\x ->
my >>= (\y ->
return (x + y)))
do-notation (করণীয়-প্রতীকগুচ্ছ) এর মাধ্যমে উপরের লাইনগুলিকে আরও শুদ্ধকরণের মাধ্যমে একটি সহজাত অনুক্রম পাওয়া যেতে পারে:
add mx my = do
x <- mx
y <- my
return (x + y)
দ্বিতীয় আরেকটি উদাহরণের সাহায্যে কীভাবে Maybe
কে আমরা সম্পূর্ণ ভিন্ন আরেকটি প্রোগ্রামিং ভাষায় ব্যবহার করা যায় সেটি দেখানো যায়: এফ#। একটি "নিরাপদ বিভাজন" ফাংশন যেটি একটি অনির্ণীত operand (প্রতীক) এর ক্ষেত্রে অথবা শূন্য দ্বারা বিভাজনের ক্ষেত্রে None
ফেরত দেয় সেটিকে গাণিতিক অভিব্যক্তির সাহায্যে প্রকাশ করা যায়:
let readNum () =
let s = Console.ReadLine()
let succ,v = Int32.TryParse(s)
if (succ) then Some(v) else None
let secure_div =
maybe {
let! x = readNum()
let! y = readNum()
if (y = 0)
then None
else return (x / y)
}
প্রোগ্রামটি কম্পাইল করার সময় কম্পাইলার অভ্যন্তরীণভাবে এই ফাংশনের সিন্ট্যাকটিক-সুগারকে অপসারণ করে নিবিড়তর bind call (আহ্বান) এর শৃঙ্খলে পরিণত করে:
maybe.Delay(fun () ->
maybe.Bind(readNum(), fun x ->
maybe.Bind(readNum(), fun y ->
if (y=0) then None else maybe.Return(x / y))))
শেষ আরেকটি উদাহরণ এইভাবে দেয়া যেতে পারে: সাধারণ মানাডিয় সূত্রসমূহ নিজেদেরকেই do-notation এর মাধ্যমে প্রকাশ করতে পারে:
do { x <- return v; f x } == do { f v }
do { x <- m; return x } == do { m }
do { y <- do { x <- m; f x }; g y } == do { x <- m; y <- f x; g y }
সুবিধাজনক হওয়া সত্ত্বেও, একজন ডেভেলপার এর মনে রাখা উচিত, এই ধরনের ব্লক স্টাইল পুরোপুরি সিন্ট্যাক্সগত এবং এদেরকে বাহ্যিকভাবে মানাডিয় (অথবা অমানাডিয় সিপিএস) অভিব্যক্তি দ্বারা প্রতিস্থাপন করা সম্ভব। bind ব্যবহার করে মানাডিয় পাইপলাইন প্রকাশ করা অনেক ক্ষেত্রে স্পষ্টতর হিসেবে বিবেচিত হয়ে থাকে, এমন কী ফাংশনাল প্রোগ্রামিং এর কিছু সংখ্যক সমর্থক যুক্তি দেখান যে, যেহেতু ব্লক-স্টাইল শিক্ষানবিশদের অনুজ্ঞামূলক প্রোগ্রামিঙের অভ্যাসগুলি বজায় রাখে, সেহেতু এগুলি পরিহার করা উচিত এবং কেবলমাত্র যখন এটি শ্রেয়তর ফলাফল প্রদান করে তখনই এটি ব্যবহার করা উচিত।[২][২৩]
প্রতিটি মানাডের দরকার, মানাডিয় সূত্রসমূহকে সিদ্ধ করে এরকম একটি নির্দিষ্ট বাস্তবায়ন, কিন্তুু, অন্যান্য প্রেক্ষিত, যেমন অন্য গঠনপ্রণালীর (স্ট্রাকচার) সাথে সম্পর্ক অথবা প্রোগ্রামিং ভাষায় সাধারণভাবে ব্যবহৃত বাক্প্রণালী, সকল মানাড কর্তৃক সমভাবে ব্যবহৃত হয়। ফলাফল স্বরূপ, ফাংশন প্রোটোটাইপ, subtyping (উপপ্রাকারিক) সম্পর্ক এবং অন্যান্য সাধারণ তথ্যের জন্য একটি সাধারণ Monad
ইন্টারফেস একটি ভাষা বা লাইব্রেরি প্রদান করতে পারে। প্রোগ্রাম উন্নয়ন (ডেভেলপ) শুরু করার জন্য একটি সুবিধাজনক পরিবেশ প্রদান করা এবং, নতুন একটি মানাড যাতে সুপারটাইপ (যেমন: ফাঙ্কটর) থেকে বৈশিষ্টপ্রাপ্ত হয় সেটি নিশ্চিত করা ছাড়াও ইন্টারফেসের বিপরীতে মানাডের নকশা পরীক্ষণ করে গুণগত মান নিয়ন্ত্রণের আরেকটি স্তর তৈরি করা সম্ভব।[তথ্যসূত্র প্রয়োজন]
অপারেটরসমূহের বিচক্ষণ ব্যবহারের মাধ্যমে মানাডিয় কোডের অধিকতর সরলীকরণ সম্ভব। map ফাংশন বিশেষভাবে সহায়ক হতে পারে, কারণ শুধুমাত্র অ্যাড-হক (বিশেষভাবে নির্মিত) মানাডিয় ফাংশন ছাড়াও এটি অন্যান্য জায়গায় ব্যবহৃত হতে পারে; যতক্ষণ পূর্ব-নির্ধারিত অপারেটরের অনুরূপভাবে মানাডিয় ফাংশনটি কাজ করতে পারে, map এর সাহায্যে সহজতর অপারেটরকে মানাডিয় অপারেটরে অবিলম্বে উন্নীত করা যেতে পারে।[চ] এই পদ্ধতির মাধ্যমে Maybe
এর উদাহরণে বর্ণীত add
এর সংজ্ঞাকে শোধন করে নিচের লাইনটি পাওয়া যায়:
add(mx,my) = map (+)
প্রক্রিয়াটিকে আরও একধাপ এগিয়ে নেয়া যায়, শুধুমাত্র Maybe
নয়, সাথে পুরো Monad
ইন্টারফেস এর জন্য add
এর সংজ্ঞা প্রদান করে। এভাবে, কোন নতুন মানাড, গঠনপ্রণালীর ইন্টারফেসের সমকক্ষ হলে নিজস্ব map বাস্তবায়ন করার সাথে সাথে উত্তরাধিকার সূত্রে add
এর একটি উন্নীত সংষ্করণের অধিকারী হবে। এক্ষেত্রে ফাংশনের কেবলমাত্র টাইপ-সাক্ষর সাধারণীকরণের প্রয়োজন:
add : (Monad Number, Monad Number) → Monad Number[২৪]
বিশ্লেষণের জন্য আরেকটি দরকারী মানাডিয় অপারেটর হচ্ছে, মানাডিয় কম্পোজিশন (রচনা করা) (এখানে ইনফিক্স >=>
দ্বারা প্রকাশ করা হয়েছে), যা আরও গাণিতিক উপায়ে মানাডিয় ফাংশনের শৃঙ্খলাবদ্ধ করা অনুমোদন করে:
(f >=> g) x = (f(x) → mb) >>= g(y = b)
এই অপারেটরের সাহায্যে, কেবলমাত্র ফাংশনের সাহায্যে মানাডিয় সূত্রসমূহ প্রকাশ করা যায়, যেটি আমাদের "একত্বের অস্তিত্ব" ও "মিশুকতার" (এসোসিয়েটিভিটি) পরস্পর সাদৃশ্য আমাদের দৃষ্টির সামনে আনয়ন করে:
(unit >=> g) ↔ g (f >=> unit) ↔ f (f >=> g) >=> h ↔ f >=> (g >=> h)[২]
গাণিতিক পর্যায়ে, সূক্ষাতিসূক্ষভাবে বিচার করলে, কিছু মানাডের চমৎকার কিছু বৈশিষ্ট্য লক্ষ্য করা যেতে পারে, যেগুলি কিছু নির্দিষ্ট সমস্যা সমাধানে অনন্য ভূমিকা পালন করে।
যে মানাড আরেকটি অতিরিক্ত, বদ্ধ, সঙ্গাভিলাষী (এসোসিয়েটিভ) দ্বিমিক অপারেটর mplus এবং mplus এর অধীনে mzero নামক একটি একত্ব উপাদান (আইডেন্টিটি এলিমেন্ট) বহন করে, তাকে বলা হয় যোগাত্মক মানাড। mzero কে Nothing
এবং লজিক্যাল অর (অথবা) অপারেটর এর একটি প্রকরণকে mplus হিসেবে ধরে Maybe
মানাডটিকে যোগাত্মক হিসেবে বিবেচনা করা যেতে পারে। List
কে যোগাত্মক মানাড হিসেবে ধরা যায় যদি, শূন্য তালিকা []
কে mzero হিসেবে, এবং সংযোজন অপারেটর ++
কে mplus হিসেবে ধরা হয়।
স্বভাবত, mzero কে অধীন টাইপের কোন মানবিহীন একটি মানাডিয় মোড়ক হিসেবে ধরা হয়ে থাকে, তবো এটিকে "শূন্য" ("এক" এর পরিবর্তে) হিসেবেও ধরা যেতে পারে যেহেতু এটি bind এর শোষক হিসেবেও কাজ করে থাকে, যা কখনও মানাডিয় ফাংশনের প্রতি নিবন্ধিত হলে mzero ফেরত দিয়ে থাকে। এই বৈশিষ্টটি দ্বিমুখী, এবং bind mzero প্রদান করবে যদি মানাডিয় শূন্য ফাংশনে কোন মান নিবন্ধন করা থাকে।
ক্যাটাগরি থিওরির ভাষায় বলতে গেলে, bind এর সাহায্যে মানাডিয় ফাংশনের ওপর (সকল মানাডের ন্যায়) এবং mplus এর সাহায্যে মানাডিয় মানসমূহের ওপর, একটি যোগাত্মক মানাড মনয়িড হিসেবে বিবেচিত হয়। [২৫][ছ]
ক্ষেত্রবিশেষে, একটি মানাডের সাধারণ রূপরেখা সহায়ক হিসেবে গণ্য হতে পারে, কিন্তু কোন মানাড ব্যবহার করা উচিত, এ বিষয়ে কোন সহজ নিয়মকানুন নেই। এই ক্ষেত্রে আমরা মুক্ত মানাডের উপযোগিতা দেখতে পাই; মানাডের ক্যাটাগরিতে একটি মুক্ত বস্তু হিসেবে, এটি মানাডিয় সূত্রসমূহের নির্দিষ্ট সীমাবদ্ধতা ছাড়াও অন্যান্য সীমাবদ্ধতা অতিক্রম করে মানাডিয় গঠনপ্রণালী উপস্থাপন করতে পারে। মুক্ত মনয়িড যেভাবে মূল্যায়ন ছাড়াই উপাদানসমূহের সংযোজন করতে সক্ষম, সেভাবেই মুক্ত মানাড কোন গভীর সেমান্টিক অর্থ আরোপ করা ছাড়াই টাইপ পদ্ধতির অনুমোদন নেয়ার জন্য চিন্থের সাহায্যে কম্পুগণনাকে শৃঙ্খলিত করতে সক্ষম।
উদাহরণস্বরূপ, কেবলমাত্র Just
এবং Nothing
চিন্থদ্বয় ব্যবহার এর মাধ্যমে Maybe
মানাড একটি মুক্ত মানাডে পরিণত হতে পারে। অন্যদিকে List
মানাড এর সংজ্ঞায় তালিকা সম্পর্কে অতিরিক্ত, নির্দিষ্ট তথ্য (যেমন append বা, জোড়া লাগান) আনয়ন করে বিধায় এটি মুক্ত মানাড নয়। একটি বিমূর্ত (অ্যাবস্ট্রাক্ট) মুক্ত মানাড যেটি unit এবং bind ও একটি পুনরাবৃত্ত রৈখিক টাইপ কন্সট্রাকটরের টাইপ চিন্থ ব্যবহার করছে সেটি ব্যবহার করে আরেকটি উদাহরণ দেয়া যেতে পারে:
newtype Free F(T) = Unit T or Bind (F, Free F(T)) unit(x) = Unit x mx >>= f = ... if mx is Unit x then ... f(x) else ... Bind (f,mx) end if
এই উদাহরণে দেখানো যোজন-তালিকা (লিঙ্কড-লিস্ট) ছাড়াও অন্যান্য গঠনপ্রণালীকে (যেমন: ট্রি) কেন্দ্র করে মুক্ত মানাড কাজ করতে পারে।
সচেতনভাবে মুক্ত মানাডের ব্যবহার অবাস্তব হিসেবে মনে হতে পারে, কিন্তু তাদের নিয়মনিষ্ঠ প্রকৃতি সিন্টাকটিক সমস্যার জন্য বিশেষভাবে উপযুক্ত। মুক্ত মানাডের সাহায্যে সিমান্টিকস বাদ দিয়ে কেবল সিন্ট্যাক্স ও টাইপ সম্পর্কে খেয়াল রাখা সক্ষম, এবং এ কারণে পার্সার ও ইন্টারপ্রিটার তৈরিতে এদের ব্যবহার হয়ে থাকে।[২৬] অন্যরা এদের আরও গতিশীল, প্রয়োগগত সমস্যা সমাধানে এদের ব্যবহার করতে পেরেছেন, যেমন, একটি প্রোগ্রামিং ভাষার মধ্যে পুনরুক্তিকারীর ব্যবস্থা করা।[২৭]
অতিরিক্ত বৈশিষ্ট সংবলিত মানাড উৎপাদন ছাড়াও কোমানাড সংজ্ঞায়িত করা সম্ভব। ধারণামূলকভাবে, মানাড যদি অধীন মানসমূহের সমন্বয়ে গঠিত কম্পুগণনাকে প্রদর্শন করে, তবে, কোমানাডসমূহ ঐ সকল মানসমূহে লঘুকরণ হিসেবে দেখা যেতে পারে। মানাডিয় কোডের, এক দিক দিয়ে দেখলে, সম্পূর্ণরূপে "মোড়ক উন্মোচন করা" সম্ভব নয়; একবার যদি কোন মানকে মানাড দ্বারা মুড়িয়ে ফেলা হয় তাহলে সেই মানটি যে কোন প্রকারের পার্শ্বপ্রতিক্রিয়া সহ ঐ মানাডের অভ্যন্তরে আলাদা অবস্থায় থাকে (বিশুদ্ধ ফাংশনাল প্রোগ্রামিং এর এটি একটি ভাল দিক)। কখনও কখনও প্রাসঙ্গিক তথ্য গ্রহণ করা নিয়ে সমস্যার সৃষ্টি হতে পারে, যেগুলি কোমানাড বিশদভাবে মুকাবিলা করতে সক্ষম।
আসলে, কোমানাড হল মানাডের ক্যাটাগরি দ্বৈত, যেটি শিথিলভাবে নির্দেশ করে, এদের প্রয়োজনীয় উপাদান একই থাকবে, কেবলমাত্র টাইপ-সাক্ষরের গতিপথ পরিবর্তিত হবে। bind-কেন্দ্রিক মানাডের সংজ্ঞা থেকে শুরু করলে, নিচের উপাদানসমূহ দিয়ে একটি কোমানাড গঠিত হবে:
counit(wa) : W T → T
=>>
দ্বারা নির্দেশ করা হয়েছে) লঘুকারী ফাংশনগুলির একটি শৃঙ্খলকে প্রসারিত করে:(wa =>> f) : (W U, W U → T) → W T[জ]
extend এবং counit কে অবশ্যই মানাডিয় সূত্রসমূহের দ্বৈতকে সিদ্ধ করতে হবে:
counit ∘ ( (wa =>> f) → wb ) ↔ f(wa) → b wa =>> counit ↔ wa wa ( (=>> f(wx = wa)) → wb (=>> g(wy = wb)) → wc ) ↔ ( wa (=>> f(wx = wa)) → wb ) (=>> g(wy = wb)) → wc
মানাডের মতই, join এর একটি দ্বৈতের সাহায্যে ফাঙ্কটর হতে কোমানাড আহরণ করা সম্ভব:
duplicate(wa) : W T → W (W T)
যদিও extend এর ন্যায় ক্রিয়াপ্রণালীকে বিপরীতমুখী করা হয়ে থাকে, তবুও একটি কোমানাড তার লক্ষিত ফাংশনগুলির বৈপরিত্য সাধন করে না, এবং ফলাফলস্বরূপ, কোমানাড নিতান্তই map বিশিষ্ট ফাঙ্কটর, কোফাঙ্কটর নয়। duplicate, counit, এবং map বিশিষ্ট এই একান্তরিত (অলটারনেট) সংজ্ঞাটিকে অবশ্যই তার নিজস্ব কোমানাড সূত্র মেনে চলতে হবে:
((map duplicate) ∘ duplicate) wa ↔ (duplicate ∘ duplicate) wa ↔ wwwa ((map counit) ∘ duplicate) wa ↔ (counit ∘ duplicate) wa ↔ wa ((map map φ) ∘ duplicate) wa ↔ (duplicate ∘ (map φ)) wa ↔ wwb
এবং মানাডের ন্যায়, দুটি গাঠনিক আকৃতিকে স্বয়ংক্রিয়ভাবে একে অপরটিতে রূপান্তরিত করা যেতে পারে:
(map φ) wa ↔ wa =>> (φ ∘ counit) wx duplicate wa ↔ wa =>> wx
wa =>> f(wx) ↔ ((map f) ∘ duplicate) wa
একটি সাধারণ উদাহরণ দেয়া যেতে পারে, Product comonad (উৎপাদ কোমানাড) যেটি একটি ইনপুটের মান ও পারিপার্শ্বিক তথ্যের ওপর ভিত্তি করে আউটপুটের মান প্রদান করে থাকে। আসলে, Product
কোমানাড হচ্ছে Writer
কোমানাড এর দ্বৈত এবং কার্যত Reader
মানাডের অনুরূপ (নিচে উভয় মানাড নিয়ে আলোচনা করা হয়েছে)। Product
এবং Reader
কেবলমাত্র যে সকল সাক্ষরের ফাংশন গ্রহণ করে, এবং, ঐসকল ফাশনের সম্পূরণ করার জন্য কীভাবে মানসমূহকে মুড়িয়ে বা মোড়ক উন্মোচন করে থাকে সেদিক দিয়ে আলাদা হয়।
একটি তাৎপর্যপূর্ণ উদাহরণ হচ্ছে Stream comonad (প্রবাহ কোমানাড) যেটি ডেটা স্ট্রিম প্রদর্শন, এবং extend এর সাহায্যে আগত সিগনালে ছাকনি (ফিল্টার) লাগাতে ব্যবহার হতে পারে। আদতে, মানাডের মত জনপ্রিয় না হলেও গবেষকগণ স্ট্রিম প্রসেসিং এবং ডাটাফ্লো প্রোগ্রামিং মডেল করার জন্য কোমানাড বিশেষভাবে সহায়ক হিসেবে খুজে পেয়েছেন।[২৮][২৯]
এদের বাধাধরা সংজ্ঞার কারণে মানাড ও কোমানাডের মধ্যে কোন কিছুকে পরস্পরের মাঝে আদানপ্রদান করা কোন সহজ ব্যাপার নয়। উচ্চস্তরের বিমূর্তন হিসেবে, অ্যারো উভয় গঠনপ্রণালীকে অন্তর্ভুক্ত করে। কিন্তু, মানাডিয় ও কোমানাডিয় কোডকে সমন্বয় করার আরও দৃঢ় উপায় বের করার জন্য বর্তমানে সক্রিয়ভাবে গবেষণা করা হচ্ছে।[৩০][৩১]
সবচাইতে সহজ মানাড হচ্ছে একত্ব মানাড, যেটা মানাডের সূত্রসমূহ সিদ্ধ করতে কেবলমাত্র সহজতম ভ্যালু ও ফাংশনগুলোকে চিন্থিত করে:
newtype Id T = T unit(x) = x (x >>= f) = f(x)
আসলেIdentity
এর বৈধ ব্যবহারও বিদ্যমান, যেমন: পর্যায়বৃত্ত মানাডিয় রুপান্তর এর জন্য একটি বেস কেস প্রদান করা। অনুজ্ঞামূলক-স্টাইলের কোড ব্লকে সাধারণ চালক নির্ধারণের ক্ষেত্রেও এটি ব্যবহার করা যেতে পারে[ঝ][তথ্যসূত্র প্রয়োজন]
যথাযথ append সহকারে যেকোন কালেকশন ইতিমধ্যে একটি মুক্ত মনয়িড হিসেবে বিবেচিত হতে পারে, কিন্তু এটি প্রতীয়মান হয় যে, List
ছাড়াও সুসংজ্ঞায়িত join সংবলিত অন্যান্য কালেকশন রয়েছে যাদের মানাড হিসেবে বিবেচনা করা যেতে পারে। append এর ওপর বিশেষ বৈশিষ্ট আরোপের মাধ্যমে List
এর পরিবর্তন ঘটিয়ে অন্যান্য মানাডিয় কালেকশনে পরিণত করা সম্ভব:[ঞ][তথ্যসূত্র প্রয়োজন]
কালেকশন | মনয়িড বৈশিষ্ট |
---|---|
তালিকা | মুক্ত |
সসীম মাল্টিসেট | কমিউটেটিভ |
সসীম সেট | |
সসীম বিন্যাস | অ-কমিউটেটিভ এবং ইডেমপোটেন্ট |
পূর্বেই বলা হয়েছে, বিশুদ্ধ কোডের কোন রকম অনিয়ন্ত্রিত পার্শ্বপ্রতিক্রিয়া থাকা চলবে না, কিন্তু এর মানে এই নয় যে, একটি প্রোগ্রাম প্রতিক্রিয়ার স্পষ্টভাবে বর্ণনা ও নিয়ন্ত্রণ হতে বিরত থাকবে। হাস্কেলের আই/ও মানাডের মূলে রয়েছে এই ধারণাটি, যেখানে IO a
টাইপের একটি বস্তুকে প্রোগ্রামের পারিপার্শ্বিক দুনিয়ার বর্তমান অবস্থা ধারণ করে আছে বলে ধরা হয়, এবং a
টাইপের একটি মান গণনা করছে বলে ধরা হয়। একটি কম্পুগণনা যা কোন মান বহন করে না – যেমন একটি প্রক্রিয়া (প্রসেডিয়র) – টাইপ IO ()
বহন করে থাকে, যা ডামি মান ()
কে "গণনা" করে। যখন একজন প্রোগ্রামার একটি ফাংশনের সাথে একটি IO
মানকে জুড়ে দেন, তখন দুনিয়ার সেই দর্শনের (ব্যবহারকারীর ইনপুট, ফাইল ইত্যাদি) ওপর ভিত্তি করে ফাংশন সিদ্ধান্ত গ্রহণ করে থাকে, এবং পরবর্তীতে নতুন পারিপার্শ্বিক অবস্থার ওপর ভিত্তি করে একটি মানাডিয় মান প্রদান করে (প্রোগ্রামের আউটপুট দেয়)। [১৯]
উদাহরণস্বরূপ, বিস্তৃত ফাইল সিস্টেমের ওপর কাজ চালানোর জন্য হাস্কেলের কিছু ফাংশন রয়েছে, যাদের মধ্যে একটির কাজ কোন ফাইলের অস্তিত্ব সম্পর্কে নিশ্চিত হওয়া এবং আরেকটির কাজ হল একটি ফাইলকে অপসারণ করা। দুটি ফাংশনের টাইপ সাক্ষর হল:
doesFileExist :: FilePath -> IO Bool
removeFile :: FilePath -> IO ()
প্রথমটি কেবলমাত্র ফাইলের অস্তিত্ব নিয়ে আগ্রহী, তাই এটি IO
মানাডের অধীনে একটি বুলিয়ান মান আউটপুট হিসেবে প্রদান করে। দ্বিতীয় ফাংশনটি ফাইল সিস্টেমের ওপর কাজ করে বিধায় এর IO
ধারকটি খাল।
IO
কেবলমাত্র ফাইল আই/ও তে সীমাবদ্ধ নয়; এটি ব্যবহারকারীর আই/ও পর্যন্ত অনুমোদন করে, এবং কিছু অনুজ্ঞাসূচক সিন্টাকটিক সুগারের বদৌলতে ধরাবাধা "ওহে বিশ্ব!" প্রোগ্রামের অনুকরণ করতে সক্ষম হয়:
main :: IO ()
main = do
putStrLn "Hello, world!"
putStrLn "What is your name, user?"
name <- getLine
putStrLn ("Nice to meet you, " ++ name ++ "!")
সিন্টাকটিক সুগার অপসারণ করলে, এটিকে নিম্নোক্ত মানাডিয় পাইপলাইনে অনুবাদ করা সম্ভব (হাস্কেলে >>
bind এর প্রকরণ হিসেবে বিবেচন করা যায় যখন মানাডিয় ক্রিয়াকে নজরে আনা হয় এবং তখন এর মূলগত ফলাফলকে আমরা উপেক্ষা করতে পারি):
main :: IO ()
main =
putStrLn "Hello, world!" >>
putStrLn "What is your name, user?" >>
getLine >>= (\name ->
putStrLn ("Nice to meet you, " ++ name ++ "!"))
আরেকটি সাধারণ পরিস্থিতি হচ্ছে একটি লগ ফাইল রাখা অথবা প্রোগ্রামের অগ্রগতির বিবরণীর ব্যবস্থা করা। ক্ষেত্রবিশেষে, একজন প্রোগ্রামার পরবর্তীতে প্রোফাইলিং বা ডিবাগিং এর জন্য নির্দিষ্ট প্রযুক্তিগত ডেটা লিপিবদ্ধ করার ইচ্ছা পোষণ করতে পারেন। এইসকল কাজ করার জন্য লেখক মানাড সহায়ক আউটপুটের সৃষ্টি করতে সক্ষম যা প্রতি পদক্ষেপে জমা হতে থাকে।
শুধুমাত্র ফাংশনাল প্রোগ্রামিং ভাষা ছাড়াও যে মানাডিয় নকশা ব্যবহার করা সম্ভব, সেটি দেখানোর জন্য নিচের উদাহরণে জাভাস্ক্রিপ্টে Writer
মানাডের বাস্তবায়ন দেখানো হয়েছে। প্রথমে, একটি অ্যারে (নেস্টেড লেজ সহ) Writer
টাইপকে একটি লিঙ্কড-লিস্ট হিসেবে গঠন করার সুযোগ প্রদান করে। অ্যারের শুন্য অবস্থানে অধীন আউটপুটের মান অবস্থান করবে এবং এক অবস্থানে সহায়ক টীকার একটি শৃঙ্খল উহ্যতভাবে অবস্থান করবে
const writer = [value, []];
unit কে সংজ্ঞায়িত করাও সহজে সম্ভব:
const unit = value => [value, []];
ডিবাগিং টীকাসমৃদ্ধ Writer
বস্তুকে আউটপুট হিসেবে প্রদান করে এমন সহজ ফাংশন সংজ্ঞায়িত করার জন্য কেবলমাত্র unit দরকার:
const squared = x => [x * x, [`${x} was squared.`]];
const halved = x => [x / 2, [`${x} was halved.`]];
সত্যিকারের মানাডের bind দরকার হয়, কিন্তু Writer
এর জন্য এর অর্থ হল, মানাডের লিঙ্কড-লিস্টে একটি ফাংশনের আউটপুট যোগ করা:
const bind = (writer, transform) => {
const [value, log] = writer;
const [result, updates] = transform(value);
return [result, log.concat(updates)];
};
নমুনা ফাংশনগুলি এখন bind এর সাহায্যে শৃঙ্খলবদ্ধ করা যেতে পারে, কিন্তু মানাডিয় রচনার (কম্পোজিশন) একটি সংষ্করণ (যেটিকে এখানে pipelog
বলা হচ্ছে) আরও নিবিড়ভাবে এই ফাংশনগুলি প্রয়োগ করতে সাহায্য করে:
const pipelog = (writer, ...transforms) =>
transforms.reduce(bind, writer);
চূড়ান্ত ফলাফল হল কম্পুগণনা ধাপে ধাপে চালানো এবং পরবর্তীতে অডিটের জন্য সেগুলির ফলাফল লিপিবদ্ধ করার মাঝে পরিষ্কারভাবে দায়িত্বের পৃথকীকরণ:
pipelog(unit(4), squared, halved);
// Resulting writer object = [8, ['4 was squared.', '16 was halved.']]
একটি পারিপার্শ্বিক মানাড (যেটিকে একটিপাঠক মানাড ফাংশন মানাড হিসেবেও অভিহিত করা হয়ে থাকে) কম্পুগণনাকে অংশীদারী পরিবেশের মাঝে মানসমূহের ওপর নির্ভরতার উপায় প্রদান করে। এই মানাডের টাইপ কন্সট্রাকটর E → T টাইপের একটি ফাংশনের ওপর একটি T টাইপের ম্যাপ করে, যেখানে E হচ্ছে অংশীদারী পরিবেশের টাইপ। মানাডিয় ফাংশনগুলি হচ্ছে:
নিচের মানাডিয় ক্রিয়াকলাপ (অপারেশন) সহায়ক হতে পারে:
ask অপারেশনটি বর্তমান প্রসঙ্গ (কনটেক্সট) উদ্ধারে ব্যবহার হয়, যেখানে local পরিবর্তিত উপপ্রসঙ্গে (সাব-কনটেক্সট) একটি কম্পুগণনা সাধন করে। কেবলমাত্র পারিপার্শ্বিক মান প্রদান করে এবং মানাডের একটি অস্তিত্বের ওপর এটি প্রয়োগ করে অবস্থা মানাডের ন্যয় পারিপার্শ্বিক মানাডের কম্পুগণনার আবাহন করা যেতে পারে।
বিধিমোতাবেক, পারিপার্শ্বিক মানাডের একটি মান, একটি অতিরিক্ত বেনামী আর্গুমেন্ট বিশিষ্ট ফাংশনের সমতুল্য; এসকেআই কম্বিনেটর ক্যালকুলাস অনুসারে return এবং bind, যথাক্রমে, K এবং S কম্বিনেটরের সমতুল্য।
একটি অবস্থা মানাড প্রোগ্রামারকে যে কোন প্রকারের কম্পপুগণনার সাথে অবস্থা সম্পর্কিত তথ্য জুড়ে দেয়ার ভূমিকা পালন করে। যদি কোন মানের টাইপ প্রদান করা হয়, তবে অবস্থা মানাডে অনুরূপ টাইপ হল একটি ফাংশন যা একটি অবস্থাকে গ্রহণ করে এবং একটি রিটার্ন মান (যার টাইপ t) সহকারে একটি নতুন অবস্থা (যার টাইপ s) প্রদান করে। এটি পারিপার্শ্বিক মানাডের অনুরূপ, পার্থক্য হল, এটি একটি নতুন অবস্থা ফেরত দেয় এবং পরিবর্তনযোগ্য পরিবেশ মডেল করার অনুমোদন দেয়।
type State s t = s -> (t, s)
উল্লেখ্য যে, এই মানাড একটি টাইপ প্যারামিটার গ্রহণ করে, যা হল অবস্থা সম্পর্কিত তথ্যের টাইপ। মানাডিয় কার্যাদি এভাবে সংজ্ঞায়িত করা যায়:
-- "return" produces the given value without changing the state.
return x = \s -> (x, s)
-- "bind" modifies m so that it applies f to its result.
m >>= f = \r -> let (x, s) = m r in (f x) s
অবস্থা সম্পর্কিত গুরুত্বপূর্ণ অপারেশন বা ক্রিয়াপ্রণালীর মাঝে রয়েছে:
get = \s -> (s, s) -- Examine the state at this point in the computation.
put s = \_ -> ((), s) -- Replace the state.
modify f = \s -> ((), f s) -- Update the state
প্রদেয় প্রাথমিক অবস্থার ওপর অবস্থা মানাডের প্রয়োগের জন্য যে অপারেশন রয়েছে:
runState :: State s a -> s -> (a, s)
runState t s = t s
অবস্থা মানাডে do-blocks হল ক্রিয়াপ্রণালীর অনুক্রম যা অবস্থা সম্পর্কিত তথ্য হালনাগাদ এবং পরীক্ষণ করতে সক্ষম।
অনানুষ্ঠানিকভাবে, S টাইপ বিশিষ্ট একটি অবস্থা মানাড টাইপ বিশিষ্ট একটি ফাংশনের ওপর T রিটার্ন মান টাইপের ম্যাপ করে, যেখানে S মানাডের অধীন অবস্থা। return এবং bind ফাংশন:
ক্যাটাগরি থিওরির দৃষ্টিকোণ থেকে দেখলে, একটি অবস্থা মানাড উৎপাদ ফাঙ্কটর এবং এক্সপোনেনশিয়াল ফাঙ্কটরের সন্ধি হতে আহরণ করা হয়, যেটি সংজ্ঞা অনুসারে যে কোন কার্তেসিয় সীমাবদ্ধ ক্যাটাগরিতে অবস্থিত .
একটি R রিটার্ন টাইপ বিশিষ্ট ধারাবাহিকতা মানাড টাইপ বিশিষ্ট ফাংশনের ওপর টাইপ T এর প্রয়োগ করে। এটি ধারাবাহিকতা-প্রদায়ক নীতির পরিকল্পনায় ব্যবহার করা হয়। রিটার্ন ও bind ফাংশনকে সংজ্ঞায়িত করা যায়:
বর্তমান-ধারাবাহিকতার-সাথে-আবাহন ফাংশনটিকে সংজ্ঞায়িত করা যেতে পারে:
কম্পুগণনা প্রতিনির্মানের (মডেলিং) বিকল্প :
সংশ্লিষ্ট ডিজাইন তত্ত্ব:
মানাডের সাধারণীকরণ:
lift
, along with multiple versions for different parameter counts, a detail ignored here.
Identity
monad can also be viewed as emerging from adjunction of any functor with its inverse.
|acces sdate=
উপেক্ষা করা হয়েছে (সাহায্য)
HaskellWiki references:
Tutorials:
Probability
monad for Markov chains.Interesting cases: