সম্প্রতি হাস্কেলের দিকে সংক্ষিপ্তভাবে নজর রেখে , একটি মোনাদ মূলত কী তা সম্পর্কে একটি সংক্ষিপ্ত, সংহত, ব্যবহারিক ব্যাখ্যা কী হবে?
আমি বেশিরভাগ ব্যাখ্যা পেয়েছি যে আমি পুরোপুরি অ্যাক্সেসযোগ্য এবং ব্যবহারিক বিশদে অভাব হতে পেরেছি।
সম্প্রতি হাস্কেলের দিকে সংক্ষিপ্তভাবে নজর রেখে , একটি মোনাদ মূলত কী তা সম্পর্কে একটি সংক্ষিপ্ত, সংহত, ব্যবহারিক ব্যাখ্যা কী হবে?
আমি বেশিরভাগ ব্যাখ্যা পেয়েছি যে আমি পুরোপুরি অ্যাক্সেসযোগ্য এবং ব্যবহারিক বিশদে অভাব হতে পেরেছি।
উত্তর:
প্রথম: আপনি যদি গণিতবিদ না হন তবে মোনাড শব্দটি কিছুটা ফাঁকা। একটি বিকল্প শব্দটি হ'ল গণনা নির্মাতা যা তারা আসলে কী কাজে লাগে তার কিছুটা বর্ণনামূলক।
আপনি ব্যবহারিক উদাহরণ জিজ্ঞাসা করুন:
উদাহরণ 1: তালিকা উপলব্ধি :
[x*2 | x<-[1..10], odd x]
এই এক্সপ্রেশনটি 1 থেকে 10 এর মধ্যে সমস্ত বিজোড় সংখ্যার দ্বিগুণ দেয় Very
দেখা যাচ্ছে যে এটি তালিকা মোনাডের মধ্যে কিছু ক্রিয়াকলাপের জন্য কেবল সিনট্যাকটিক চিনি। একই তালিকা অনুধাবন লিখিত হতে পারে:
do
x <- [1..10]
guard (odd x)
return (x * 2)
অথবা এমনকি:
[1..10] >>= (\x -> guard (odd x) >> return (x*2))
উদাহরণ 2: ইনপুট / আউটপুট :
do
putStrLn "What is your name?"
name <- getLine
putStrLn ("Welcome, " ++ name ++ "!")
উভয় উদাহরণে মনড, একেএ গণনা নির্মাতারা ব্যবহার করা হয়েছে। সাধারণ থিম যে একসংখ্যা চেইন অপারেশন কিছু নির্দিষ্ট, দরকারী উপায়। তালিকার বোধগমিতে, ক্রিয়াকলাপগুলি এমনভাবে শৃঙ্খলিত হয় যে যদি কোনও ক্রিয়াকলাপ কোনও তালিকা ফিরিয়ে দেয়, তবে নীচের ক্রিয়াকলাপগুলি তালিকার প্রতিটি আইটেমটিতে সম্পাদিত হয় । অন্যদিকে আইও মনাদ ক্রমানুসারে ক্রিয়াকলাপ সম্পাদন করে তবে একটি "লুকানো ভেরিয়েবল" পাশ করে, যা "বিশ্বের অবস্থা" উপস্থাপন করে, যা আমাদেরকে খাঁটি কার্যকরী পদ্ধতিতে আই / ও কোড লেখার অনুমতি দেয়।
এটি চেইন অপারেশনগুলির প্যাটার্নটি বেশ কার্যকর এবং হ্যাসকেলে প্রচুর বিভিন্ন জিনিসের জন্য ব্যবহৃত হয়।
অপর একটি উদাহরণ ব্যতিক্রম: Error
মোনাদ ব্যবহার করে , ক্রিয়াকলাপগুলি এমনভাবে শৃঙ্খলিত হয় যেগুলি ক্রমানুসারে সঞ্চালিত হয়, যদি কোনও ত্রুটি নিক্ষেপ করা হয় তবে এই ক্ষেত্রে অবশিষ্ট শৃঙ্খলটি পরিত্যাগ করা হয়।
>>=
অপারেটরটি ব্যবহার করে চেইন অপারেশনের জন্য তালিকা-বোঝার সিনট্যাক্স এবং না-স্বীকৃতি উভয়ই সিনট্যাকটিক চিনি । একটি মোনাড মূলত কেবল এক প্রকার যা >>=
অপারেটরকে সমর্থন করে ।
উদাহরণ 3: পার্সার
এটি একটি খুব সাধারণ পার্সার যা কোনও উদ্ধৃত স্ট্রিং বা একটি সংখ্যাকে পার্স করে:
parseExpr = parseString <|> parseNumber
parseString = do
char '"'
x <- many (noneOf "\"")
char '"'
return (StringValue x)
parseNumber = do
num <- many1 digit
return (NumberValue (read num))
অপারেশন char
, digit
ইত্যাদি খুব সহজ are তারা হয় মেলে না মিলছে না। ম্যাজিকটি হ'ল মোনাড যা নিয়ন্ত্রণ প্রবাহ পরিচালনা করে: কোনও ম্যাচ ব্যর্থ না হওয়া অবধি ক্রিয়াকলাপ সম্পাদন করা হয়, সেক্ষেত্রে মোনাড সর্বশেষে ব্যাকট্র্যাক <|>
করে এবং পরবর্তী বিকল্পটি চেষ্টা করে। আবার কিছু অতিরিক্ত, দরকারী শব্দার্থক দিয়ে শৃঙ্খলাবদ্ধ অপারেশনগুলির একটি উপায়।
উদাহরণ 4: অ্যাসিনক্রোনাস প্রোগ্রামিং
উপরের উদাহরণগুলি হাস্কেলের মধ্যে রয়েছে, তবে এটি প্রমাণ করে যে এফ # এছাড়াও মনাদদের সমর্থন করে। এই উদাহরণটি ডন সিম থেকে চুরি করা হয়েছে :
let AsyncHttp(url:string) =
async { let req = WebRequest.Create(url)
let! rsp = req.GetResponseAsync()
use stream = rsp.GetResponseStream()
use reader = new System.IO.StreamReader(stream)
return reader.ReadToEnd() }
এই পদ্ধতিটি একটি ওয়েব পৃষ্ঠা আনে। পাঞ্চ লাইনটি এর ব্যবহার GetResponseAsync
- এটি প্রকৃতপক্ষে পৃথক থ্রেডের প্রতিক্রিয়ার জন্য অপেক্ষা করে, যখন মূল থ্রেডটি ফাংশন থেকে ফিরে আসে। সাড়া পাওয়ার পরে শেষ তিনটি রেখাটি তৈরি হওয়া থ্রেডে কার্যকর করা হয়।
বেশিরভাগ অন্যান্য ভাষায় আপনাকে স্পষ্টভাবে প্রতিক্রিয়াটি পরিচালনা করে এমন রেখাগুলির জন্য পৃথক ফাংশন তৈরি করতে হবে। async
একসংখ্যা "বিভাজিত করা" তার নিজের উপর ব্লক সক্ষম হয় এবং পরেরটির অর্ধেক সঞ্চালনের স্থগিত। ( async {}
বাক্য গঠনটি ইঙ্গিত দেয় যে ব্লকের নিয়ন্ত্রণ প্রবাহটি async
মোনাড দ্বারা সংজ্ঞায়িত করা হয়েছে ))
তারা কিভাবে কাজ করে
সুতরাং একটি মোনাড কীভাবে এই সমস্ত অভিনব নিয়ন্ত্রণ-প্রবাহ জিনিসটি করতে পারে? ডু-ব্লক (বা এফ # তে বলা হয় এমন একটি গণনার এক্সপ্রেশন ) আসলে যা ঘটে থাকে তা হ'ল প্রতিটি ক্রিয়াকলাপ (মূলত প্রতিটি লাইন) একটি পৃথক বেনাম ফাংশনে আবৃত থাকে। এই ফাংশনগুলি পরে bind
অপারেটরটি ( >>=
হাস্কেলের বানান ) ব্যবহার করে সংযুক্ত করা হয় । যেহেতু bind
অপারেশনটি ফাংশনগুলিকে একত্রিত করে, এটি উপযুক্ত হিসাবে এটিগুলি কার্যকর করতে পারে: ক্রমানুসারে, একাধিক বার, বিপরীতভাবে, কিছুকে ফেলে দিন, কিছুটিকে আলাদা থ্রেডে চালানো যখন এটির মতো মনে হয় এবং এ জাতীয় কিছু।
একটি উদাহরণ হিসাবে, এটি উদাহরণ 2 থেকে আইও-কোডের প্রসারিত সংস্করণ:
putStrLn "What is your name?"
>>= (\_ -> getLine)
>>= (\name -> putStrLn ("Welcome, " ++ name ++ "!"))
এটি কুরুচিপূর্ণ তবে বাস্তবে কী চলছে তা আরও স্পষ্ট। >>=
অপারেটর জাদু উপাদান: এটা (ডান দিকে) একটি ফাংশন সঙ্গে (বাম দিকে) একটি মান এবং এটি সম্মিলন লাগে, একটি নতুন মান উত্পাদন করতে। এই নতুন মানটি পরবর্তী >>=
অপারেটর দ্বারা নেওয়া হয় এবং আবার একটি ফাংশনের সাথে একত্রিত হয়ে একটি নতুন মান উত্পাদন করে। >>=
মিনি-মূল্যায়নকারী হিসাবে দেখা যেতে পারে।
নোটটি যে >>=
বিভিন্ন ধরণের জন্য ওভারলোড হয় তাই প্রতিটি মোনাডের নিজস্ব প্রয়োগ রয়েছে >>=
। (চেইনের সমস্ত ক্রিয়াকলাপ একই মনডের ধরণের হওয়া উচিত যদিও অন্যথায় >>=
অপারেটর কাজ করবে না))
>>=
কেবলমাত্র সহজতম বাস্তবায়নটি বাম দিকের মানটি নেয় এবং ডানদিকে ফাংশনে এটি প্রয়োগ করে এবং ফলাফলটি ফিরে আসে, তবে আগে যেমন বলেছিল, মোনাডের বাস্তবায়নে যখন অতিরিক্ত কিছু চলছে তখন পুরো প্যাটার্নটি কী কার্যকর হয়? >>=
।
এক ক্রিয়াকলাপ থেকে অন্য ক্রিয়াকলাপগুলিতে কীভাবে মানগুলি পাস হয় সে সম্পর্কে কিছু অতিরিক্ত চালাকতা রয়েছে তবে এটি হাস্কেল টাইপ সিস্টেমটির আরও গভীর ব্যাখ্যা প্রয়োজন।
সাতরে যাও
হাস্কেল-পদে একটি মোনাড একটি প্যারামিটারাইজড টাইপ যা মোনাড টাইপ শ্রেণীর উদাহরণ, যা >>=
আরও কয়েকটি অপারেটরগুলির সাথে সংজ্ঞায়িত করে। সাধারণ ব্যক্তির ভাষায়, একটি মোনাড কেবলমাত্র এক প্রকারের জন্য >>=
অপারেশনটি সংজ্ঞায়িত করা হয়।
নিজেই >>=
ফাংশন chaining শুধু একটি কষ্টকর পথ, কিন্তু do-স্বরলিপি যা লুকিয়ে রাখে "নদীর গভীরতানির্ণয়", পরমাণুসদৃশ্য অপারেশন সক্রিয় আউট একটি খুব সুন্দর এবং দরকারী বিমূর্ততা হতে, দরকারী অনেক জায়গায় ভাষায় উপস্থিতি, এবং দরকারী সঙ্গে ভাষায় আপনার নিজস্ব মিনি-ভাষা তৈরির জন্য।
কেন মণাদ শক্ত?
অনেক হাস্কেল-শিখার জন্য, মনডগুলি একটি বাধা যা তারা ইটের প্রাচীরের মতো আঘাত করে। এটি এমন নয় যে মনডগুলি নিজেরাই জটিল, তবে বাস্তবায়ন প্যারামিটারাইজড টাইপ, টাইপ ক্লাস ইত্যাদির মতো আরও অনেক উন্নত হাস্কেল বৈশিষ্ট্যের উপর নির্ভর করে। সমস্যাটি হ্যাস্কেল আই / ও মনডের উপর ভিত্তি করে তৈরি হয়েছে এবং নতুন ভাষা শেখার সময় আপনি যে প্রথম জিনিসগুলি বুঝতে চান তা সম্ভবত I / O - এর পরেও এমন কোনও প্রোগ্রাম তৈরি করা খুব মজাদার নয় যা কোনও ফল দেয় না আউটপুট। আই / ও-এর মতো চিকিত্সা করা ও ডিম ছাড়াই আমার কাছে তাত্ক্ষণিক সমাধান নেই, যতক্ষণ না আপনার ভাষার অন্যান্য অংশগুলির সাথে পর্যাপ্ত অভিজ্ঞতা না হয়। দুঃখিত।
মনাদে দুর্দান্ত ব্লগ: http://adit.io/posts/2013-04-17-functors ,_applicatives ,_ এবং_মোনাদ_ইন_পিকচারস html
"একটি মোনাড কী" ব্যাখ্যা করা কিছুটা "সংখ্যাটি কী?" আমরা সর্বদা সংখ্যা ব্যবহার করি। তবে কল্পনা করুন যে আপনি এমন কোনও ব্যক্তির সাথে সাক্ষাত করেছেন যিনি সংখ্যা সম্পর্কে কিছুই জানেন না। কিভাবে নরক আপনি ব্যাখ্যা করবে কি সংখ্যার আছে? এবং কীভাবে আপনি এটি বর্ণনা করতে শুরু করবেন কেন এটি কার্যকর হতে পারে?
মোনাদ কী? সংক্ষিপ্ত উত্তর: এটি এক সাথে চেইন অপারেশনের একটি নির্দিষ্ট উপায়।
সংক্ষেপে, আপনি মৃত্যুদন্ড কার্যকর করার পদক্ষেপগুলি লিখছেন এবং এগুলিকে "বাইন্ড ফাংশন" এর সাথে সংযুক্ত করছেন। (হাসকেলে, এর নাম দেওয়া হয়েছে >>=
) আপনি নিজেই বাইন্ড অপারেটরকে কলগুলি লিখতে পারেন বা আপনি সিনট্যাক্স চিনির ব্যবহার করতে পারেন যা সংকলকটি আপনাকে সেই ফাংশন কলগুলি সন্নিবেশ করিয়ে দেয়। তবে যেভাবেই হোক না কেন, প্রতিটি ধাপ এই বাইন্ড ফাংশনটির কল দ্বারা পৃথক করা হয়।
সুতরাং বাইন্ড ফাংশনটি সেমিকোলনের মতো; এটি একটি প্রক্রিয়াতে পদক্ষেপগুলি পৃথক করে। বাইন্ড ফাংশনের কাজ হ'ল পূর্ববর্তী পদক্ষেপটি থেকে আউটপুট নেওয়া এবং এটি পরবর্তী ধাপে ফিড করা।
এটা খুব শক্ত লাগছে না, তাই না? তবে একাধিক ধরণের মোনাড রয়েছে। কেন? কিভাবে?
ওয়েল, বাঁধাই করা ফাংশন করতে মাত্র এক ধাপ থেকে ফলাফলের নিই এবং পরবর্তী ধাপে এটা ভোজন। তবে যদি এটি "সব" হয় তবে মোনাদ ... এটি আসলে খুব কার্যকর নয়। এবং এটি বোঝার জন্য গুরুত্বপূর্ণ: প্রতিটি দরকারী মনড কেবল একটি মোনাদ হওয়া ছাড়াও অন্য কিছু করে । প্রতিটি দরকারী মনডের একটি "বিশেষ শক্তি" থাকে, যা এটি অনন্য করে তোলে।
(একটি মোনাড যা বিশেষ কিছু করে না তাকে "পরিচয় মোনাড" বলা হয় Rather
মূলত, প্রতিটি মনডের বাইন্ড ফাংশনটির নিজস্ব প্রয়োগ রয়েছে। এবং আপনি যেমন একটি বাইন্ড ফাংশন লিখতে পারেন এটি কার্যকর করার পদক্ষেপগুলির মধ্যে হুপি জিনিসগুলি করে। উদাহরণ স্বরূপ:
যদি প্রতিটি পদক্ষেপ সাফল্য / ব্যর্থতার সূচকটি দেয়, আপনি পূর্ববর্তীটি সফল হলেই পরবর্তী পদক্ষেপটি কার্যকর করতে পারবেন ind এইভাবে, একটি ব্যর্থ পদক্ষেপ আপনার কাছ থেকে কোনও শর্তাধীন পরীক্ষা ছাড়াই পুরো ক্রমটি "স্বয়ংক্রিয়ভাবে" বাতিল করে দেয় ab ( ব্যর্থ মনাদ ।)
এই ধারণাটি প্রসারিত করে, আপনি "ব্যতিক্রমগুলি" প্রয়োগ করতে পারেন। ( ত্রুটি মোনাড বা ব্যতিক্রম মোনাড ।) যেহেতু আপনি সেগুলি ভাষা বৈশিষ্ট্য না হয়ে সেগুলি নিজেরাই সংজ্ঞায়িত করছেন, তারা কীভাবে কাজ করে তা আপনি নির্ধারণ করতে পারেন। (উদাহরণস্বরূপ, সম্ভবত আপনি প্রথম দুটি ব্যতিক্রম উপেক্ষা করতে চান এবং তৃতীয় ব্যতিক্রম ছোঁড়া হলে কেবল বাতিল করা উচিত ))
আপনি প্রতিটি পদক্ষেপে একাধিক ফলাফল প্রত্যাবর্তন করতে পারেন এবং সেগুলির উপর আবদ্ধ ফাংশন লুপ রাখতে পারেন এবং প্রতিটিটিকে আপনার জন্য পরবর্তী পদক্ষেপে খাওয়ান। এইভাবে, একাধিক ফলাফলের সাথে ডিল করার সময় আপনাকে পুরো জায়গা জুড়ে লুপগুলি লিখতে হবে না। বাইন্ড ফাংশন "স্বয়ংক্রিয়ভাবে" আপনার জন্য সমস্ত কিছু করে। ( তালিকা মোনাড ।)
পাশাপাশি "ধাপে" এক ধাপ থেকে অন্য ধাপে যাওয়ার সময়, আপনার কাছে বাইন্ড ফাংশন পাশাপাশি অতিরিক্ত ডেটাও পাস হতে পারে। এই ডেটাটি এখন আপনার উত্স কোডে প্রদর্শিত হবে না, তবে আপনি প্রতিটি ফাংশনে ম্যানুয়ালি পাস না করে আপনি যে কোনও জায়গা থেকে এখনও এটি অ্যাক্সেস করতে পারবেন। ( পাঠক মনাদ ।)
আপনি এটি তৈরি করতে পারেন যাতে "অতিরিক্ত ডেটা" প্রতিস্থাপন করা যায়। এটি আপনাকে ধ্বংসাত্মক আপডেটগুলি না করেই ধ্বংসাত্মক আপডেটগুলি তৈরি করতে দেয়। ( রাজ্য মনাদ এবং তার চাচাত ভাই লেখক মনাদ ।)
যেহেতু আপনি কেবল ধ্বংসাত্মক আপডেটগুলিই অনুকরণ করছেন , আপনি তুচ্ছভাবে এমন কিছু করতে পারেন যা বাস্তব ধ্বংসাত্মক আপডেটগুলির দ্বারা অসম্ভব । উদাহরণস্বরূপ, আপনি শেষ আপডেটটি পূর্বাবস্থায় ফেরাতে পারেন বা পুরানো সংস্করণে ফিরে যেতে পারেন ।
আপনি এমন একটি মোনাড তৈরি করতে পারেন যেখানে গণনাগুলি বিরতি দেওয়া যায় , যাতে আপনি আপনার প্রোগ্রামটি থামিয়ে দিতে পারেন, অভ্যন্তরীণ স্থিতির ডেটা দিয়ে ভিতরে যেতে পারেন এবং আবার এটি শুরু করতে পারেন।
আপনি মোনাদ হিসাবে "ধারাবাহিকতা" প্রয়োগ করতে পারেন। এটি আপনাকে মানুষের মন ভাঙতে দেয় !
এগুলি এবং আরও অনেক কিছুই সোনাদির সাহায্যে সম্ভব। অবশ্যই, এই সব এছাড়াও পুরোপুরি সম্ভব ছাড়া monads খুব। এটি স্নাদ ব্যবহার করে খুব মারাত্মকভাবে সহজ ।
আসলে, মনাদাদের সাধারণ বোঝার বিপরীতে, তাদের রাষ্ট্রের সাথে কিছুই করার নেই। মনডস কেবল জিনিস মোড়ানোর উপায় এবং এটি মোড়ানো না করে মোড়ানো স্টাফগুলিতে অপারেশন করার পদ্ধতি সরবরাহ করে।
উদাহরণস্বরূপ, আপনি হাসকেলে অন্য একটি মোড়ানোর জন্য একটি প্রকার তৈরি করতে পারেন:
data Wrapped a = Wrap a
জিনিস মোড়ানো আমরা সংজ্ঞায়িত
return :: a -> Wrapped a
return x = Wrap x
Unwrapping ছাড়া কাজগুলি করতে বলতে আপনি একটি ফাংশন আছে f :: a -> b
, তাহলে আপনি এটা করতে পারেন করতে উত্তোলন যে ফাংশন আবৃত মান কাজ করার জন্য:
fmap :: (a -> b) -> (Wrapped a -> Wrapped b)
fmap f (Wrap x) = Wrap (f x)
এটাই বোঝার মতো বিষয়। তবে, দেখা যাচ্ছে যে এই উত্তোলনটি করার আরও একটি সাধারণ ফাংশন রয়েছে যা হ'ল bind
:
bind :: (a -> Wrapped b) -> (Wrapped a -> Wrapped b)
bind f (Wrap x) = f x
bind
এর চেয়ে কিছুটা বেশি করতে পারে fmap
তবে বিপরীতে নয়। বাস্তবিক, fmap
শুধুমাত্র পদ সংজ্ঞায়িত করা যায় bind
এবং return
। সুতরাং, যখন কোনও মোনাড সংজ্ঞায়িত করা হয় .. আপনি তার ধরণটি দিন (এটি এখানে ছিল Wrapped a
) এবং তারপরে বলুন যে এটির return
এবং bind
অপারেশনগুলি কীভাবে কাজ করে।
দুর্দান্ত জিনিসটি হ'ল এটি এমন একটি সাধারণ প্যাটার্নে পরিণত হয়েছে যে এটি সমস্ত স্থান জুড়ে যায়, খাঁটি উপায়ে encapsulating রাষ্ট্র তাদের মধ্যে কেবল একটি।
কিভাবে monads কার্মিক নির্ভরতা পরিচয় করিয়ে দিতে এবং এইভাবে মূল্যায়ন ক্রম নিয়ন্ত্রণ, মত Haskell, এর আই ব্যবহার করা হয় একসংখ্যা, চেক আউট করতে ব্যবহার করা যেতে পারে একটি ভাল নিবন্ধ জন্য আই ইনসাইড ।
মনড বোঝার জন্য, এটি সম্পর্কে খুব বেশি চিন্তা করবেন না। আপনি কী আকর্ষণীয় মনে করেন সেগুলি সম্পর্কে তাদের পড়ুন এবং এখনই বুঝতে না পারলে চিন্তিত হবেন না। তারপরে হাস্কেলের মতো ভাষায় ডাইভিংয়ের উপায়। মনডস এই জিনিসগুলির মধ্যে একটি যেখানে অনুশীলনের মাধ্যমে আপনার মস্তিষ্কে ট্রিক্স বোঝা যায়, একদিন আপনি হঠাৎ বুঝতে পারেন যে আপনি সেগুলি বুঝতে পেরেছেন।
তবে, আপনি Monads উদ্ভাবন করতে পারে!
সিগফ্প বলেছেন:
তবে এগুলির সমস্তই ব্যাখ্যাটির প্রয়োজন হিসাবে কিছু মোদ্রকে প্রগাot়ভাবে পরিচয় করিয়ে দেয়। তবে আমি যে যুক্তি দিতে চাই তা হ'ল তারা মোটেও গুপ্ত নয়। প্রকৃতপক্ষে, কার্যকরী প্রোগ্রামিংয়ে বিভিন্ন সমস্যার মুখোমুখি হয়ে আপনি অবিচ্ছিন্নভাবে কিছু সমাধানের দিকে পরিচালিত হতেন, এগুলি সবই স্নাদের উদাহরণ। প্রকৃতপক্ষে, আমি আশা করি আপনি ইতিমধ্যে তাদের আবিষ্কার করে আনতে পারেন যদি আপনি ইতিমধ্যে না করে থাকেন। তারপরে এটি একটি ছোট পদক্ষেপ লক্ষ্য করুন যে এই সমস্ত সমাধানগুলি আসলে ছদ্মবেশে একই সমাধান। এবং এটি পড়ার পরে, আপনি মনদেজের অন্যান্য নথিগুলি বুঝতে আরও ভাল অবস্থানে থাকতে পারেন কারণ আপনি যা কিছু দেখেন তা আপনি ইতিমধ্যে উদ্ভাবিত কিছু হিসাবে স্বীকৃতি দেবেন।
মনডস যে সমস্যাগুলি সমাধান করার চেষ্টা করেন তাদের অনেকগুলি পার্শ্ব প্রতিক্রিয়া সম্পর্কিত সম্পর্কিত। সুতরাং আমরা তাদের দিয়ে শুরু করব। (নোট করুন যে মনডস আপনাকে পার্শ্ব প্রতিক্রিয়াগুলি হ্যান্ডেল করার চেয়ে আরও বেশি কিছু করতে দেয়, বিশেষত অনেক ধরণের ধারক বস্তুকে সোনারূপ হিসাবে দেখা যেতে পারে mon মনাদদের কিছু প্রবর্তনের ফলে মনদ্রের এই দুটি পৃথক ব্যবহারের পুনর্মিলন করা এবং কেবলমাত্র একটিতে মনোনিবেশ করা শক্ত মনে হয় অন্যটি.)
C ++ এর মতো একটি অত্যাবশ্যক প্রোগ্রামিং ভাষায় ফাংশন গণিতের ফাংশনের মতো কিছুই করে না। উদাহরণস্বরূপ, ধরুন আমাদের একটি সি ++ ফাংশন রয়েছে যা একটি একক ভাসমান পয়েন্ট আর্গুমেন্ট গ্রহণ করে এবং একটি ভাসমান পয়েন্ট ফলাফল প্রদান করে। অতিমাত্রায় এটি গাণিতিক ফাংশনকে বাস্তবের সাথে ম্যাপিংয়ের মতো কিছুটা মনে হতে পারে, তবে সি ++ ফাংশন তার যুক্তিগুলির উপর নির্ভর করে কেবল একটি সংখ্যা ফেরানোর চেয়ে আরও অনেক কিছু করতে পারে। এটি স্ক্রিনে আউটপুট লিখার পাশাপাশি ব্যবহারকারীর কাছ থেকে ইনপুট গ্রহণের পাশাপাশি গ্লোবাল ভেরিয়েবলের মানগুলি পড়তে এবং লিখতে পারে। একটি খাঁটি কার্যকরী ভাষায়, তবে কোনও ফাংশন তার যুক্তিগুলিতে কেবল যা সরবরাহ করা হয় তা কেবল এটিই পড়তে পারে এবং এটি যে মূল্য ফেরত দেয় তার মাধ্যমে এটি বিশ্বকে প্রভাবিত করতে পারে way
একটি মোনাড একটি ডেটাটাইপ যার দুটি অপারেশন রয়েছে: >>=
(ওরফে bind
) এবং return
(ওরফে unit
)। return
একটি স্বেচ্ছাসেবী মান নেয় এবং এটি দিয়ে মনডের একটি উদাহরণ তৈরি করে। >>=
মোনাডের উদাহরণ গ্রহণ করে এবং এটির উপরে একটি ফাংশন মানচিত্র করে। (আপনি ইতিমধ্যে দেখতে পাচ্ছেন যে একটি মোনাড একটি অদ্ভুত ধরণের ডেটাটাইপ, যেহেতু বেশিরভাগ প্রোগ্রামিং ভাষায় আপনি কোনও ফাংশন লিখতে পারেননি যা একটি স্বেচ্ছাসেবী মান নেয় এবং এটি থেকে কোনও প্রকার তৈরি করে Mon মনড একধরণের প্যারামেট্রিক পলিমারফিজম ব্যবহার করে ))
হাস্কেল নোটেশনে, মোনাদ ইন্টারফেসটি লেখা আছে
class Monad m where
return :: a -> m a
(>>=) :: forall a b . m a -> (a -> m b) -> m b
এই অপারেশন নির্দিষ্ট "আইন" মান্য করা অনুমিত হয়, কিন্তু যে terrifically গুরুত্বপূর্ণ নয়: "আইন" শুধু সংকেত লিপিবদ্ধ উপায় অপারেশনের যুক্তিসম্মত বাস্তবায়নের মূলত আচরণ করে (কর্তব্য, যে >>=
এবং return
কিভাবে মান একসংখ্যা দৃষ্টান্ত এবং রুপান্তরিত পেতে সম্পর্কে একমত হতে কর্তব্য এটি >>=
সাহসী)।
মনডগুলি কেবল রাষ্ট্র এবং আই / ও সম্পর্কে নয়: তারা গণনার একটি সাধারণ প্যাটার্ন বিমূর্ত করে যার মধ্যে রাষ্ট্র, আই / ও, ব্যতিক্রম এবং অ-নির্ধারণবাদ নিয়ে কাজ করা অন্তর্ভুক্ত থাকে। সম্ভবত বোঝার জন্য সবচেয়ে সহজ মনডগুলি হ'ল তালিকাগুলি এবং বিকল্প ধরণের:
instance Monad [ ] where
[] >>= k = []
(x:xs) >>= k = k x ++ (xs >>= k)
return x = [x]
instance Monad Maybe where
Just x >>= k = k x
Nothing >>= k = Nothing
return x = Just x
তালিকার কনস্ট্রাক্টরগুলি কোথায় []
এবং :
সেগুলি ++
হ'ল কনকান্টেশন অপারেটর এবং Just
এবং Nothing
তারা Maybe
কনস্ট্রাক্টর। এই উভয় মনাদ নিজ নিজ ডেটা প্রকারে গণনার সাধারণ এবং দরকারী নিদর্শনগুলিকে আবদ্ধ করে রাখুন (নোট করুন যে এর পার্শ্ব প্রতিক্রিয়া বা আই / ও এর সাথে কোনও সম্পর্ক নেই)।
মোনাডগুলি কী কী এবং সেগুলি কেন কার্যকর তা উপলব্ধি করার জন্য আপনাকে কিছু অ-তুচ্ছ হাস্কেল কোড লেখার আশেপাশে খেলতে হবে।
আপনার প্রথমে বুঝতে হবে একটি ফান্টেক্টর কী। তার আগে, উচ্চ-অর্ডার ফাংশনগুলি বুঝতে।
একটি উচ্চতর ক্রম ফাংশন কেবল একটি ফাংশন যা কোনও ফাংশনকে আর্গুমেন্ট হিসাবে গ্রহণ করে।
একজন functor কোনো ধরনের নির্মাণ T
, যার জন্য একটি উচ্চ-অর্ডার ফাংশন অস্তিত্ব আছে, সেটিতে কল map
, যে রূপান্তরগুলির ধরনের একটি ফাংশন a -> b
(যে কোন দুই ধরনের দেওয়া a
এবং b
) একটি ফাংশন মধ্যে T a -> T b
। এই map
ক্রিয়াকলাপটি অবশ্যই পরিচয় এবং সংমিশ্রনের আইনগুলি মেনে চলতে হবে যাতে নিম্নলিখিত এক্সপ্রেশনগুলি সকলের জন্য সত্য হয়ে যায় p
এবং q
(হাস্কেল স্বরলিপি):
map id = id
map (p . q) = map p . map q
উদাহরণস্বরূপ, কোনও ধরণের কন্সট্রাক্টর নামক List
ফান্টেক্টর যদি এটি কোনও ধরনের ফাংশন দিয়ে সজ্জিত হয় (a -> b) -> List a -> List b
যা উপরের আইনগুলি মানায়। একমাত্র বাস্তব বাস্তবায়ন সুস্পষ্ট। ফলস্বরূপ List a -> List b
ফাংশন প্রদত্ত তালিকার উপরে পুনরাবৃত্তি করে, (a -> b)
প্রতিটি উপাদানটির জন্য ফাংশনটি কল করে এবং ফলাফলগুলির তালিকা প্রদান করে।
একজন একসংখ্যা মূলত শুধু একটি functor হয় T
দুটি অতিরিক্ত পদ্ধতি সঙ্গে, join
টাইপ এর T (T a) -> T a
আর unit
(কখনও কখনও বলা return
, fork
অথবা pure
ধরনের) a -> T a
। হাস্কেলের তালিকাগুলির জন্য:
join :: [[a]] -> [a]
pure :: a -> [a]
কেন এটি দরকারী? কারণ আপনি উদাহরণস্বরূপ, map
কোনও ফাংশন সহ একটি তালিকার উপরে যা একটি তালিকা ফেরত পারে। Join
তালিকাগুলির ফলস্বরূপ তালিকাটি গ্রহণ করে এবং তাদের সাথে সম্মিলিত করে। List
এটি একটি মোনাড কারণ এটি সম্ভব।
আপনি একটি ফাংশন যা লিখতে পারেন map
, তাহলে join
। এই ফাংশনটি বলা হয় bind
, বা flatMap
, বা (>>=)
, বা (=<<)
। এটি সাধারণত হ্যাসকেলে একটি মোনাড উদাহরণ দেওয়া হয়।
একটি মোনাডকে কিছু আইন পূরণ করতে হয়, এটি join
অবশ্যই সাহসী হতে হবে। এর অর্থ হল আপনার যদি x
টাইপের মান থাকে [[[a]]]
তবে join (join x)
সমান হওয়া উচিত join (map join x)
। আর pure
এর জন্য একটি পরিচয় হতে হবে join
যেমন যে join (pure x) == x
।
[অস্বীকৃতি: আমি এখনও পুরোপুরি মনডকে কুঁচকানোর চেষ্টা করছি। নীচেরটি আমি এখনও পর্যন্ত বুঝতে পেরেছি তা কেবল এটিই। যদি এটি ভুল হয়, আশা করি কোনও জ্ঞানী কেউ আমাকে কার্পেটে ডাকবেন]]
অর্ণার লিখেছেন:
মনডস কেবল জিনিস মোড়ানোর উপায় এবং এটি মোড়ানো না করে মোড়ানো স্টাফগুলিতে অপারেশন করার পদ্ধতি সরবরাহ করে।
ঠিক এটা। ধারণাটি এরকম হয়:
আপনি কিছু ধরণের মান নেন এবং কিছু অতিরিক্ত তথ্য দিয়ে এটি মুড়িয়ে রাখেন। মানটি যেমন একটি নির্দিষ্ট ধরণের (যেমন একটি পূর্ণসংখ্যা বা একটি স্ট্রিং), তেমনি অতিরিক্ত তথ্য একটি নির্দিষ্ট ধরণের।
উদাহরণস্বরূপ, অতিরিক্ত তথ্য হতে পারে একটি Maybe
বা একটি IO
।
তারপরে আপনার কিছু অপারেটর রয়েছে যা আপনাকে অতিরিক্ত তথ্য বহন করার সময় মোড়ানো ডেটাতে কাজ করতে দেয়। এই অপারেটরগুলি মোড়ানো মানের সাথে কীভাবে অপারেশনের আচরণ পরিবর্তন করতে হবে তা সিদ্ধান্ত নিতে অতিরিক্ত তথ্য ব্যবহার করে।
যেমন, একটি Maybe Int
হতে পারে একটি Just Int
বা Nothing
। এখন, আপনি একটি যোগ Maybe Int
একটি থেকে Maybe Int
, অপারেটর যদি তারা উভয় দেখতে চেক করবে Just Int
ভিতরে গুলি, এবং তাই যদি, মোড়ক খোলা হবে Int
গুলি তাদের উপরন্তু অপারেটর পাস, পুনরায় মোড়ানো ফলে Int
একটি নতুন মধ্যে Just Int
(যা একটি বৈধ Maybe Int
), এবং এইভাবে ফিরে আসুন Maybe Int
। তবে যদি তাদের মধ্যে একটি Nothing
অভ্যন্তরীণ ছিল , এই অপারেটরটি কেবল অবিলম্বে ফিরে আসবে Nothing
, যা আবার একটি বৈধ Maybe Int
। এইভাবে, আপনি ভান করতে পারেন যে আপনার Maybe Int
গুলি কেবলমাত্র সাধারণ সংখ্যা এবং এগুলিতে নিয়মিত গণিত করতে পারেন। আপনি যদি একটি পেতে হলে Nothing
, আপনার সমীকরণ এখনও সঠিক ফল হবে - তোমার জন্য শিবিকা চেক করেও Nothing
সর্বত্র ।
তবে উদাহরণটি কেবল তার জন্য ঘটে Maybe
। অতিরিক্ত তথ্য যদি একটি হয় IO
, তবে IO
এর জন্য সংজ্ঞায়িত বিশেষ অপারেটরটির পরিবর্তে কল করা হবে এবং সংযোজন সম্পাদনের আগে এটি সম্পূর্ণ আলাদা কিছু করতে পারে। (ঠিক আছে, দু'জন IO Int
একসাথে যুক্ত করা সম্ভবত অযৌক্তিক - আমি এখনও নিশ্চিত নই।) (এছাড়াও, আপনি যদি Maybe
উদাহরণের দিকে মনোযোগ দেন তবে আপনি লক্ষ্য করেছেন যে "অতিরিক্ত জিনিস দিয়ে মূল্য মুছা" সবসময় সঠিক নয় But তবে এটি শক্ত নিখুঁত, সঠিক এবং নির্ভুল হতে হবে অনিচ্ছাকৃত না হয়ে))
মূলত, "মোনাড" এর অর্থ মোটামুটি "প্যাটার্ন" । তবে অনানুষ্ঠানিকভাবে ব্যাখ্যা করা এবং নির্দিষ্ট করে দেওয়া প্যাটার্নস সমৃদ্ধ একটি বইয়ের পরিবর্তে আপনার কাছে এখন একটি ভাষা নির্মাণ - সিনট্যাক্স এবং সমস্ত - যা আপনাকে আপনার প্রোগ্রামের জিনিস হিসাবে নতুন নিদর্শনগুলি ঘোষণা করতে দেয় । (এখানে ছদ্মবেশটি সমস্ত নিদর্শনগুলিকে একটি নির্দিষ্ট ফর্ম অনুসরণ করতে হবে, সুতরাং একটি মোনাড একটি নিদর্শন হিসাবে যথেষ্ট জেনেরিক নয় But তবে আমি মনে করি এটি সবচেয়ে কাছের শব্দটি যা বেশিরভাগ লোক জানে এবং বুঝতে পারে))
এবং সে কারণেই লোকেরা মনাদাদের এত বিভ্রান্তি খুঁজে পান: কারণ তারা এ জাতীয় জেনেরিক ধারণা। কোন কিছুকে কী মোডান করে তোলে তা জিজ্ঞাসা করা অনুরূপভাবে অস্পষ্ট যা কোনও জিনিসকে কী নমুনা করে তোলে তা জিজ্ঞাসা করা।
তবে কোনও প্যাটার্নের ধারণার জন্য ভাষায় সিনট্যাক্টিক সমর্থন থাকার কী কী প্রভাব রয়েছে তা চিন্তা করুন: গ্যাং অফ ফোর বইটি পড়ার পরিবর্তে এবং কোনও নির্দিষ্ট প্যাটার্নের নির্মাণকে মুখস্ত করার পরিবর্তে আপনি কেবল এমন কোড লিখুন যা এই প্যাটার্নটিকে অগ্নিবিদ্যায় প্রয়োগ করে, জেনেরিক উপায় একবার এবং তারপর আপনি সম্পন্ন! তারপরে আপনি এই প্যাটার্নটিকে পুনরায় ব্যবহার করতে পারেন, যেমন ভিজিটর বা স্ট্র্যাটেজি বা ফ্যাদেড বা যে কোনও কিছুই, কেবল আপনার কোডের সাথে ক্রিয়াকলাপগুলি সজ্জিত করে, বারবার এটি প্রয়োগ না করে!
সুতরাং যেহেতু মোনাডগুলি বোঝে এমন লোকেরা এগুলিকে দরকারী বলে মনে করেন : এটি কিছু আইভরি টাওয়ার ধারণা নয় যে বুদ্ধিজীবী snobs বোঝার জন্য নিজেকে গর্বিত করে (ঠিক আছে, এটি অবশ্যই, তেহি) তবে কোডটি সহজ করে তোলে।
M (M a) -> M a
। আপনি M a -> (a -> M b) -> M b
এটিকে যে কোনও একটিতে পরিণত করতে পারেন তা হ'ল যা তাদের দরকারী করে তোলে।
অনেক চেষ্টা করার পরেও আমি মনে করি অবশেষে আমি মোনাড বুঝি। অতিমাত্রায় শীর্ষে ভোট দেওয়া জবাব সম্পর্কে আমার নিজের দীর্ঘ সমালোচনাটি পড়ার পরে, আমি এই ব্যাখ্যাটি পেশ করব।
মনড বোঝার জন্য এখানে তিনটি প্রশ্নের উত্তর দেওয়া দরকার:
যেমনটি আমি আমার মূল মন্তব্যে উল্লেখ করেছি, মোনাডের অনেকগুলি ব্যাখ্যা question নং প্রশ্নে ধরা পড়ে, ছাড়াই এবং যথাযথভাবে পর্যাপ্ত প্রশ্ন 2, বা প্রশ্ন 1 আচ্ছাদন করার আগে।
তোমার কেন মোনাদ লাগবে?
হাস্কেলের মতো খাঁটি কার্যকরী ভাষা সি, বা জাভা এর মতো অপরিহার্য ভাষাগুলির চেয়ে পৃথক, খাঁটি ফাংশনাল প্রোগ্রামটি অবশ্যই নির্দিষ্ট ক্রমে একবারে এক ধাপে সম্পাদিত হয় না। একটি হাস্কেল প্রোগ্রাম একটি গাণিতিক ফাংশনের অনুরূপ, যাতে আপনি সম্ভাব্য ক্রমের যে কোনও সংখ্যায় "সমীকরণ" সমাধান করতে পারেন। এটি বিভিন্ন সুবিধাগুলি প্রদান করে, যার মধ্যে এটি হ'ল নির্দিষ্ট ধরণের বাগের সম্ভাবনা দূর করে, বিশেষত "রাষ্ট্র" এর মতো বিষয় সম্পর্কিত।
যাইহোক, কিছু নির্দিষ্ট সমস্যা রয়েছে যা এই স্টাইলের প্রোগ্রামিং দিয়ে সমাধান করা এত সহজ নয়। কনসোল প্রোগ্রামিং এবং ফাইল আই / ও-এর মতো কিছু জিনিস নির্দিষ্ট জিনিসগুলিতে ঘটতে হবে বা রাষ্ট্র বজায় রাখতে হবে। এই সমস্যাটির সাথে মোকাবিলা করার একটি উপায় হ'ল এক ধরণের অবজেক্ট তৈরি করা যা কোনও গণনার অবস্থাকে প্রতিনিধিত্ব করে এবং একটি ক্রিয়াকলাপ যা একটি রাজ্য অবজেক্টকে ইনপুট হিসাবে গ্রহণ করে এবং একটি নতুন পরিবর্তিত রাষ্ট্রের বস্তুটি ফিরিয়ে দেয়।
সুতরাং আসুন একটি অনুমান "রাষ্ট্র" মান তৈরি করুন, যা একটি কনসোল স্ক্রিনের অবস্থা উপস্থাপন করে। এই মানটি কীভাবে নির্মিত হবে তা গুরুত্বপূর্ণ নয়, তবে আসুন এটি বাইট দৈর্ঘ্যের আসকি অক্ষরগুলির একটি অ্যারে যা বর্তমানে স্ক্রিনে দৃশ্যমান তা উপস্থাপন করে এবং সিউডোকোডে ব্যবহারকারী দ্বারা প্রবেশ করা ইনপুটটির শেষ লাইনকে উপস্থাপন করে এমন একটি অ্যারে আমরা কিছু ফাংশন সংজ্ঞায়িত করেছি যা কনসোলের স্থিতি নেয়, এটি সংশোধন করে এবং নতুন কনসোলের স্থিতি ফিরিয়ে দেয়।
consolestate MyConsole = new consolestate;
সুতরাং কনসোল প্রোগ্রামিং করতে, তবে খাঁটি কার্যকরী পদ্ধতিতে, আপনাকে প্রত্যেকের ভিতরে অনেকগুলি ফাংশন কল বাসাতে হবে।
consolestate FinalConsole = print(input(print(myconsole, "Hello, what's your name?")),"hello, %inputbuffer%!");
কনসোলে পরিবর্তনগুলি নির্দিষ্ট ক্রমে ঘটতে বাধ্য করার জন্য এইভাবে প্রোগ্রামিং "খাঁটি" কার্যকরী শৈলী রাখে। তবে, আমরা সম্ভবত উপরের উদাহরণের মতো একযোগে কয়েকটি অপারেশন করার চেয়ে আরও বেশি কিছু করতে চাই। এইভাবে বাসা বাঁধার কাজগুলি কদাচিৎ হতে শুরু করবে। আমরা যা চাই তা হ'ল কোড যা মূলত উপরের মতো একই জিনিসটি করে, তবে আরও কিছুটা এভাবে লেখা হয়:
consolestate FinalConsole = myconsole:
print("Hello, what's your name?"):
input():
print("hello, %inputbuffer%!");
এটি সত্যিই এটি লেখার আরও সুবিধাজনক উপায় হবে। যদিও আমরা কীভাবে এটি করব?
মোনাদ কী?
একবার আপনার টাইপ (যেমন consolestate
) পরে আপনি সেই ধরণের কাজ করার জন্য বিশেষভাবে নকশা করা বিভিন্ন গুচ্ছ ফাংশন সংজ্ঞায়িত করার পরে আপনি :
স্বয়ংক্রিয়ভাবে (বাইন্ড) অপারেটর সংজ্ঞায়িত করে এই জিনিসগুলির পুরো প্যাকেজটিকে "মোনাড" রূপান্তর করতে পারেন তার ডানদিকে ফাংশন প্যারামিটারগুলিতে এবং তার lift
অপারেটার যা সাধারণ ফাংশনগুলিকে সেই নির্দিষ্ট ধরণের বাইন্ড অপারেটরের সাথে কাজ করে এমন ফাংশনে রূপান্তর করে যা তার বাম দিকে ফেরত মানগুলি ফিড করে ।
একটি মোনাড কীভাবে প্রয়োগ করা হয়?
অন্যান্য উত্তরগুলি দেখুন, এটির বিশদটিতে ঝাঁপিয়ে পড়া বেশ নিখরচায় seem
কয়েক বছর আগে এই প্রশ্নের উত্তর দেওয়ার পরে, আমি বিশ্বাস করি যে আমি এই প্রতিক্রিয়ার সাথে উন্নতি করতে এবং সরল করতে পারি ...
একটি মোনাড একটি ফাংশন রচনা কৌশল যা সংমিশ্রণ ফাংশন ব্যবহার করে কিছু ইনপুট পরিস্থিতিতে চিকিত্সা বহিরাগত করে, রচনা bind
চলাকালীন প্রাক-প্রক্রিয়া ইনপুট করতে।
সাধারণ রচনাতে, ক্রিয়াকলাপটি, compose (>>)
তার পূর্বসূরীর ক্রম অনুসারে রচিত ফাংশনটি প্রয়োগ করতে ব্যবহৃত হয়। গুরুত্বপূর্ণভাবে, রচনা করা হচ্ছে ফাংশনটি এর ইনপুটটির সমস্ত পরিস্থিতিতে পরিচালনা করতে হবে।
(x -> y) >> (y -> z)
এই নকশাকে ইনপুট পুনর্গঠন করে উন্নত করা যেতে পারে যাতে প্রাসঙ্গিক রাজ্যগুলি আরও সহজেই জিজ্ঞাসাবাদ করতে পারে। সুতরাং, পরিবর্তে কেবল y
মানটি Mb
যেমন হয়ে উঠতে পারে , উদাহরণস্বরূপ, (is_OK, b)
যদি y
বৈধতার ধারণা অন্তর্ভুক্ত থাকে ।
উদাহরণস্বরূপ, যখন ইনপুটটি কেবল কোনও সংখ্যার হয় তবে ডায়রিটিযুক্ত কোনও সংখ্যক থাকে বা না থাকতে পারে এমন স্ট্রিংয়ের পরিবর্তে, আপনি টাইপটিকে একটিতে পুনর্গঠন করতে পারেন bool
, একটি বৈধ সংখ্যা উপস্থিতি এবং যেমন tuple একটি নম্বর ইঙ্গিত bool * float
। রচিত ফাংশনগুলিতে এখন কোনও সংখ্যা বিদ্যমান কিনা তা নির্ধারণের জন্য ইনপুট স্ট্রিংকে বিশ্লেষণের প্রয়োজন হবে না তবে কেবলমাত্র bool
একটি টিউপলের অংশটি পরীক্ষা করতে পারে ।
(Ma -> Mb) >> (Mb -> Mc)
এখানে, আবারও, রচনাটি প্রাকৃতিকভাবে ঘটে compose
এবং তাই প্রতিটি ফাংশনকে অবশ্যই তার ইনপুটটির সমস্ত দৃশ্য পৃথকভাবে পরিচালনা করতে হবে যদিও এটি করা এখন অনেক সহজ।
যাইহোক, যদি আমরা সেই সময়ের জন্য জিজ্ঞাসাবাদের প্রয়াসকে বহিরাগত করতে পারি যেখানে পরিস্থিতি পরিচালনা করা রুটিন is উদাহরণস্বরূপ, যখন আমাদের প্রোগ্রামটি ইনপুট ঠিক মতো না হয় তখন is_OK
কী হয় false
। যদি এটি করা হয়ে থাকে তবে রচিত ফাংশনগুলির জন্য সেই দৃশ্যটি নিজেরাই পরিচালনা করার প্রয়োজন হবে নাটকীয়ভাবে তাদের কোডটি সরলকরণ এবং পুনরায় ব্যবহারের অন্য স্তরের উপর প্রভাব ফেলতে হবে।
এই বহিরাগতকরণটি অর্জন করতে আমরা একটি ফাংশন ব্যবহার করতে পারি bind (>>=)
, এর composition
পরিবর্তে সঞ্চালন করতে compose
। যেমন, পরিবর্তে কেবল অন্যের ইনপুট এক ফাংশনের আউটপুট থেকে মান হস্তান্তর Bind
পরিদর্শন করবে M
এর অংশ Ma
কিনা তা স্থির এবং কিভাবে গঠিত ফাংশন প্রয়োগ করতে a
। অবশ্যই, ফাংশনটি bind
বিশেষভাবে আমাদের বিশেষভাবে সংজ্ঞায়িত করা হবেM
করা হবে যাতে এটির কাঠামোটি পরিদর্শন করতে এবং আমরা যা যা অ্যাপ্লিকেশন চাই তা সম্পাদন করতে সক্ষম হতে পারি। যাইহোক, এটি a
যে কোনও কিছু হতে পারে যেহেতু এটি প্রয়োজনীয় অ্যাপ্লিকেশনটি নির্ধারণ করার পরে bind
কেবল a
রচিত ফাংশনটিতেই অনির্দিষ্টকে পাস করে । অতিরিক্তভাবে, রচিত ফাংশনগুলি তাদের সাথে আর ডিল করার প্রয়োজন নেইM
ইনপুট কাঠামোর অংশ, তাদের সরল করে। অত: পর ...
(a -> Mb) >>= (b -> Mc)
বা আরও সংক্ষেপে Mb >>= (b -> Mc)
সংক্ষেপে, একটি মোনাড বাহ্যিক রূপ দেয় এবং এরপরে ইনপুটটি তাদের পর্যাপ্ত পরিমাণে প্রকাশের জন্য নকশাকৃত হয়ে গেলে কিছু ইনপুট পরিস্থিতিতে চিকিত্সার চারপাশে মানক আচরণ সরবরাহ করে। এই নকশাটি এমন একটি shell and content
মডেল যেখানে শেলটি রচিত ফাংশনের প্রয়োগের সাথে সম্পর্কিত ডেটা ধারণ করে এবং জিজ্ঞাসাবাদ করে এবং কেবলমাত্র উপলব্ধ থাকেbind
।
অতএব, একটি monad তিনটি জিনিস:
M
মনাদ সম্পর্কিত তথ্য রাখার জন্য শেল, bind
ফাংশন বিষয়বস্তু মান স্থিরীকৃত ফাংশন (গুলি) এটি শেল মধ্যে খুঁজে বের করে তার অ্যাপ্লিকেশানের মধ্যে এই শেল তথ্যের ব্যবহার করতে বাস্তবায়িত এবং a -> Mb
, ফলাফল উত্পাদন করে যা মোনাদিক পরিচালনা ডেটা অন্তর্ভুক্ত করে।সাধারণভাবে বলতে গেলে কোনও ফাংশনে ইনপুটটি তার আউটপুট থেকে অনেক বেশি সীমাবদ্ধ যা এতে ত্রুটির শর্ত হিসাবে কিছু অন্তর্ভুক্ত থাকতে পারে; অতএব, Mb
ফলাফল কাঠামো সাধারণত খুব দরকারী। উদাহরণস্বরূপ, বিভাজনকারী যখন থাকে তখন বিভাগ অপারেটর কোনও নম্বর দেয় না 0
।
অতিরিক্তভাবে, monad
s এর মধ্যে মোড়ক কার্যগুলিকে অন্তর্ভুক্ত করা যেতে পারে যা মানগুলি, a
মোনাডিক ধরণে Ma
এবং সাধারণ ফাংশনগুলিকে, a -> b
মোনাডিক ফাংশনগুলিতে, a -> Mb
প্রয়োগের পরে তাদের ফলাফল মোড়ানো দ্বারা অন্তর্ভুক্ত করতে পারে। অবশ্যই, যেমন bind
, এর মতো মোড়ানো ফাংশন নির্দিষ্ট M
। একটি উদাহরণ:
let return a = [a]
let lift f a = return (f a)
এর নকশা bind
ফাংশনটির অপরিবর্তনীয় ডেটা স্ট্রাকচার এবং খাঁটি ফাংশনগুলি মনে করে যে অন্যান্য জিনিস জটিল হয় এবং গ্যারান্টি দেওয়া যায় না। এমনিতেই মনডাক আইন রয়েছে:
প্রদত্ত ...
M_
return = (a -> Ma)
f = (a -> Mb)
g = (b -> Mc)
তারপর ...
Left Identity : (return a) >>= f === f a
Right Identity : Ma >>= return === Ma
Associative : Ma >>= (f >>= g) === Ma >>= ((fun x -> f x) >>= g)
Associativity
এর অর্থ হ'ল bind
কখন bind
প্রয়োগ করা হয় নির্বিশেষে মূল্যায়নের ক্রম সংরক্ষণ করে । অর্থাৎ সংজ্ঞা Associativity
আলাদা উপরের, বল তাড়াতাড়ি মূল্যায়ন binding
এর f
এবং g
শুধু তাই আশা একটি ফাংশন পরিণাম ডেকে আনবে Ma
অনুক্রমে সম্পূর্ণ করতে bind
। সুতরাং Ma
এর মান প্রয়োগ হওয়ার আগে অবশ্যই মূল্যায়ন নির্ধারণ করতে হবে f
এবং ফলস্বরূপ এর প্রয়োগ হবে g
।
একটি মোনাড কার্যকরভাবে "টাইপ অপারেটর" এর একটি রূপ। এটি তিনটি কাজ করবে। প্রথমে এটি "মোড়ানো" (বা অন্যথায় রূপান্তরিত) এক প্রকারের মানকে অন্য ধরণের (সাধারণত "মোনাডিক টাইপ" বলা হয়) রূপান্তরিত করে। দ্বিতীয়ত এটি অন্তর্নিহিত ধরণের সমস্ত ক্রিয়াকলাপ (বা ফাংশন) মোনাদিক ধরণের উপর উপলভ্য করে দেবে। অবশেষে এটি একটি যৌথ মোনাড উত্পাদন করতে অন্য স্বাদের সাথে এর স্ব সংযুক্ত করার জন্য সহায়তা সরবরাহ করবে।
"হতে পারে মোনাড" মূলত ভিজ্যুয়াল বেসিক / সি # তে "nlalable প্রকার" এর সমতুল্য। এটি একটি অপ্রয়োজনীয় প্রকারের "টি" লাগে এবং এটিকে "নলেবল <T>" রূপান্তর করে এবং তারপরে সমস্ত বাইনারি অপারেটর একটি নল <<> এর অর্থ কী তা বোঝায়।
পার্শ্ব প্রতিক্রিয়া একইভাবে উপস্থাপন করা হয়। একটি কাঠামো তৈরি করা হয় যা কোনও ফাংশনের রিটার্ন মানের পাশাপাশি পার্শ্ব প্রতিক্রিয়াগুলির বিবরণ ধারণ করে। "উত্তোলিত" ক্রিয়াকলাপগুলি তারপরে পার্শ্ব প্রতিক্রিয়াগুলির অনুলিপি হিসাবে ফাংশনগুলির মধ্যে মানগুলি পাস করা হয়।
এগুলিকে বেশ কয়েকটি কারণে "টাইপ অপারেটর" -র সহজ-সহজে উপলব্ধি করা নামের চেয়ে "মনাদস" বলা হয়:
(উত্তরগুলিও দেখুন মোনাদ কী? )
মোনাডসের কাছে একটি ভাল অনুপ্রেরণা হ'ল সিগফ্পে (ড্যান পিপোনি) এর আপনি মোনাড আবিষ্কার করতে পারতেন! (এবং হয়তো আপনি ইতিমধ্যেই আছে) । আছে অন্য একসংখ্যা টিউটোরিয়াল অনেকটা , যার অনেকগুলোই misguidedly "সরল শর্তাদি" বিভিন্ন অ্যানালজিস ব্যবহারে monads ব্যাখ্যা করতে চেষ্টা: এই হল একসংখ্যা টিউটোরিয়াল ভ্রান্ত ধারণা ; তাদের এড়ানো।
ডিআর ম্যাকআইভার যেমন বলেছেন যে আপনার ভাষা কেন সফল হয় :
সুতরাং, হাস্কেল সম্পর্কে আমি ঘৃণিত জিনিসগুলি:
এর সুস্পষ্ট সঙ্গে শুরু করা যাক। মোনাড টিউটোরিয়াল। না, মনাদ নয়। বিশেষত টিউটোরিয়াল এরা অবিরাম, উদীয়মান এবং প্রিয় godশ্বর তারা ক্লান্তিকর। তদুপরি, আমি সত্যিকারের সাহায্য করার কোনও দৃinc়প্রত্যয়ী প্রমাণ দেখিনি। শ্রেণীর সংজ্ঞাটি পড়ুন, কিছু কোড লিখুন, ভয়ের নামটি পান।
তুমি বলেছ তুমি মোনাদ বোঝে? ভাল, আপনি নিজের পথে আছেন কেবলমাত্র অন্য মনাদ ব্যবহার শুরু করুন এবং তাড়াতাড়ি বা পরে আপনি বুঝতে পারবেন সাধারণভাবে কী রয়েছে।
[আপনি যদি গাণিতিকভাবে মনোনিবেশিত হন তবে আপনি কয়েক ডজন টিউটোরিয়াল উপেক্ষা করে সংজ্ঞাটি শিখতে বা বিভাগ তত্ত্বের বক্তৃতাগুলি অনুসরণ করতে চাইতে পারেন :) সংজ্ঞাটির মূল অংশটি হ'ল একটি মোনাড এম একটি "টাইপ কনস্ট্রাক্টর" জড়িত যা প্রতিটিটির জন্য সংজ্ঞা দেয় বিদ্যমান টাইপ "টি" একটি নতুন টাইপ "এমটি", এবং "নিয়মিত" ধরণের এবং "এম" ধরণের মধ্যে পিছনে যাওয়ার কিছু উপায়]]
এছাড়াও আশ্চর্যজনকভাবে যথেষ্ট, স্নাতকের সর্বোত্তম পরিচিতিগুলির মধ্যে একটি হল কার্যত প্রোগ্রামিংয়ের জন্য ফিলিপ ওয়েডলারের মনডসকে পরিচয় করিয়ে দেওয়া প্রাথমিক একাডেমিক গবেষণাপত্র । এটিতে ব্যবহারিক, তুচ্ছ- অনুপ্রেরণামূলক উদাহরণ রয়েছে, সেখানে কৃত্রিম টিউটোরিয়ালের অনেকগুলি ভিন্ন।
মনডসগুলি প্রবাহকে নিয়ন্ত্রণ করতে হয় যে ডেটাগুলিতে বিমূর্ত ডাটা প্রকারগুলি কী।
অন্য কথায়, অনেক বিকাশকারীগণ সেট, তালিকাগুলি, অভিধান (বা হ্যাশ, বা মানচিত্র) এবং গাছগুলির ধারণা দিয়ে স্বাচ্ছন্দ্য বোধ করেন। এই তথ্য প্রকারের মধ্যে অনেকগুলি বিশেষ কেস রয়েছে (উদাহরণস্বরূপ InsertionOrderPreservingIdentityHashMap)।
যাইহোক, প্রোগ্রাম "প্রবাহ" এর সাথে মোকাবিলা করার সময় অনেকগুলি বিকাশকারী, সুইচ / কেস, ডিওটিও, গেটো (জিআর) এবং (সম্ভবত) সমাপনীকরণের চেয়ে আরও অনেকগুলি নির্মাণের মুখোমুখি হননি।
সুতরাং, একটি মোনাড কেবল একটি নিয়ন্ত্রণ প্রবাহের নির্মাণ। মোনাড প্রতিস্থাপনের জন্য আরও ভাল বাক্যাংশটি হবে 'কন্ট্রোল টাইপ'।
যেমন একটি মোনাডের নিয়ন্ত্রণ যুক্তি, বা বিবৃতি, বা ফাংশনগুলির জন্য স্লট রয়েছে - ডেটা স্ট্রাকচারের সমতুল্য বলতে হবে যে কোনও ডেটা স্ট্রাকচার আপনাকে ডেটা যুক্ত করতে এবং এটি সরাতে দেয়।
উদাহরণস্বরূপ, "যদি" মোনাদ:
if( clause ) then block
এর সর্বাধিকতম দুটি স্লট রয়েছে - একটি ক্লজ এবং একটি ব্লক। if
একসংখ্যা সাধারণত দফা ফল মূল্যায়নের নির্মিত হয়, এবং যদি মিথ্যাতে থাকে, ব্লক নির্ণয় করা। অনেক বিকাশকারীরা 'যদি' শিখেন তখন মোনেদের সাথে পরিচয় হয় না এবং কার্যকর যুক্তি লেখার জন্য মনাদদের বোঝার প্রয়োজন হয় না।
মনডস আরও জটিল হয়ে উঠতে পারে, একইভাবে ডেটা স্ট্রাকচার আরও জটিল হয়ে উঠতে পারে তবে মোনাডের অনেকগুলি বিস্তৃত বিভাগ রয়েছে যা একই রকম শব্দার্থক হতে পারে, তবে বাস্তবায়ন এবং বাক্য গঠন পৃথক করে।
অবশ্যই, একইভাবে ডেটা স্ট্রাকচারগুলি পুনরাবৃত্তি হতে পারে বা ট্র্যাভার করা যেতে পারে, মনডগুলি মূল্যায়ন করা যেতে পারে।
সংকলকগুলির ব্যবহারকারীর দ্বারা সংজ্ঞায়িত মনাদগুলির জন্য সমর্থন থাকতে পারে বা নাও থাকতে পারে। হাস্কেল অবশ্যই করেন। আইওকে কিছু অনুরূপ ক্ষমতা রয়েছে, যদিও মোনাদ শব্দটি ভাষায় ব্যবহৃত হয় না।
আমার প্রিয় মনাদ টিউটোরিয়াল:
http://www.haskell.org/haskellwiki/All_About_Monads
("মোনাড টিউটোরিয়াল" এর জন্য গুগল অনুসন্ধানে ১ 170০,০০০ হিটগুলির মধ্যে!)
@ এসটিটু: মনডসের মূল বিন্দুটি হ'ল অন্যথায় খাঁটি কোডটিতে আপনাকে (সাধারণত) অনুক্রমিক শব্দার্থক যোগ করার অনুমতি দেয়; এমনকি আপনি মোনাডগুলি রচনা করতে পারেন (মোনাড ট্রান্সফর্মারগুলি ব্যবহার করে) এবং আরও আকর্ষণীয় এবং জটিল সম্মিলিত শব্দার্থক শব্দগুলি পেতে পারেন, যেমন ত্রুটি পরিচালনা, ভাগ করে নেওয়া অবস্থা এবং লগিংয়ের পার্সিংয়ের মতো। খাঁটি কোডে এগুলি সবই সম্ভব, মোনাডস আপনাকে এটিকে বিমূর্ত করতে এবং মডিউলার লাইব্রেরিতে (প্রোগ্রামিংয়ে সর্বদা ভাল) পুনরায় ব্যবহার করার অনুমতি দেয়, পাশাপাশি এটি প্রয়োজনীয় প্রয়োজন বোধ করার জন্য সুবিধাজনক বাক্য গঠন সরবরাহ করে।
হাস্কেলের ইতিমধ্যে অপারেটর ওভারলোডিং রয়েছে [1]: এটি জাভা বা সি # তে যেভাবে ইন্টারফেস ব্যবহার করতে পারে সেভাবে প্রকারের ক্লাস ব্যবহার করে তবে হাস্কেল কেবল অ্যান্ডফানিউমারিক টোকেনকে + && এবং> যেমন ইনফিক্স শনাক্তকারী হিসাবে মঞ্জুরি দেয়। আপনার যদি এটি বোঝায় যে "সেমিকোলন ওভারলোডিং" [২] তবে এটি কেবলমাত্র আপনার চালকের দিকে ওভারলোডিং operator এটি কালো যাদুর মতো বলে মনে হচ্ছে এবং "সেমিকোলন ওভারলোড" (চিত্রের উদ্যোগী পার্ল হ্যাকাররা এই ধারণাটি পেয়েছে) সমস্যাটি বলার মত কথা বলেছে তবে মুল্যটি হচ্ছে যে মনড ছাড়া কোনও অর্ধিকোলন নেই, যেহেতু বিশুদ্ধভাবে কার্যকরী কোডের সুস্পষ্ট সিকোয়েন্সিংয়ের প্রয়োজন হয় না বা অনুমতি দেওয়া হয় না।
এটি প্রয়োজনের চেয়ে আরও জটিল মনে হচ্ছে। সিগফ্পের নিবন্ধটি বেশ দুর্দান্ত তবে এটি ব্যাখ্যা করার জন্য হাস্কেল ব্যবহার করেছে, কোন ধরণের হাস্কেলকে মোনাডসকে বোঝার জন্য মুরগী এবং ডিমের সমস্যা ভাঙ্গতে ব্যর্থ হয়েছে এবং হাস্কেলকে কুঁকড়ে ফেলার জন্য মোনডস বোঝা যাচ্ছে।
[1] এটি মোনাড থেকে পৃথক সমস্যা তবে মনাদগুলি হাস্কেলের অপারেটর ওভারলোডিং বৈশিষ্ট্যটি ব্যবহার করে।
[২] এটি একটি ওভারস্প্লিমিফিকেশন যেহেতু মোনাডিক অ্যাকশনগুলিকে শৃঙ্খলাবদ্ধ করার জন্য অপারেটরটি >> = (উচ্চারিত "বাঁধাই") তবে সেখানে সিনট্যাকটিক চিনির ("কর") রয়েছে যা আপনাকে ব্রেস এবং সেমিকোলন এবং / অথবা ইনডেন্টেশন এবং নিউলাইনগুলি ব্যবহার করতে দেয়।
আমি ইদানীং অন্যভাবে মনডাদের কথা ভাবছি। আমি তাদের গাণিতিক উপায়ে মৃত্যুদন্ড কার্যকর করার আদেশকে বিমূর্ত করার কথা ভাবছিলাম যা নতুন ধরণের পলিমারফিজমকে সম্ভব করে তোলে।
যদি আপনি একটি অপরিহার্য ভাষা ব্যবহার করেন এবং আপনি কিছু ক্রমটি ক্রমটি লিখে থাকেন তবে কোডটি সর্বদা সেই ক্রমে চলে।
এবং সাধারণ ক্ষেত্রে, যখন আপনি একটি মোনাড ব্যবহার করেন, এটি একইরকম অনুভূত হয় - আপনি ক্রমের সাথে সংঘটিত অভিব্যক্তিগুলির একটি তালিকা সংজ্ঞায়িত করেন। আপনি যদি কোন মোনাড ব্যবহার করেন তার উপর নির্ভর করে আপনার কোডটি এক সাথে একাধিক আইটেমের সমান্তরালভাবে (আইও মোনাডের মতো) চলতে পারে (তালিকার মোনাডের মতো), এটি পার্টওয়ে দিয়ে থামতে পারে (সম্ভবত মোনাডের মতো) , এটি কিছুটা পরে থেমে থেমে পরে পুনরায় শুরু হতে পারে (যেমন একটি পুনঃসমন মোডের মতো), এটি আবার শুরু হতে পারে এবং শুরু থেকে শুরু হতে পারে (যেমন একটি লেনদেনের মতো), বা অন্য বিকল্পগুলি চেষ্টা করার জন্য এটি কিছুটা পার হয়ে যেতে পারে (যেমন লজিক মোনাডের মতো) ।
এবং যেহেতু মনাদগুলি বহুপদী, আপনার প্রয়োজনের উপর নির্ভর করে বিভিন্ন মনদে একই কোড চালানো সম্ভব।
এছাড়াও, কিছু ক্ষেত্রে, একই সাথে একাধিক বৈশিষ্ট্য পাওয়ার জন্য এক সাথে (ম্যানাদ ট্রান্সফর্মার সহ) একত্রিত করা সম্ভব হয়।
আমি এখনও মনাদাদের কাছে নতুন, তবে আমি ভেবেছিলাম যে একটি লিঙ্কটি শেয়ার করব যা আমি দেখতে পেলাম যা সত্যই পড়েছে (চিত্রগুলির সাথে !!): http://www.matusiak.eu/numerodix/blog/2012/3/11/ মেনাদস-ফর-দ্য লেইম্যান / (কোনও সম্পর্ক নেই)
মূলত, নিবন্ধটি থেকে আমি যে উষ্ণ এবং अस्पष्ट ধারণাটি পেয়েছি সে ধারণাটি ছিল যে ম্যানডগুলি মূলত অ্যাডাপ্টার যা পৃথক ফাংশনগুলিকে একটি সামঞ্জস্যপূর্ণ ফ্যাশনে কাজ করতে দেয়, অর্থাত্ একাধিক ফাংশন যুক্ত করতে এবং মিশ্রিত করতে সক্ষম এবং বেমানান ফিরে আসার বিষয়ে চিন্তা না করে তাদের সাথে মেলে and প্রকার এবং যেমন। সুতরাং আমরা যখন এই অ্যাডাপ্টারগুলি তৈরি করার চেষ্টা করছি তখন বিন্দু ফাংশন আপেল এবং কমলার সাথে কমলা দিয়ে আপেল রাখার দায়িত্বে থাকে। এবং লিফট ফাংশনটি "নিম্ন স্তরের" ফাংশনগুলি গ্রহণ এবং তাদের BIND ফাংশনগুলির সাথে কাজ করার জন্য এবং "আপগ্রেড" করার জন্য দায়িত্বে রয়েছে এবং পাশাপাশি সংযোজিতও হতে পারে।
আমি আশা করি আমি এটি সঠিকভাবে পেয়েছি এবং আরও গুরুত্বপূর্ণভাবে, আশা করি যে নিবন্ধটি মনদেসে একটি বৈধ মতামত রয়েছে। আর কিছু না হলে এই নিবন্ধটি মনদেদের সম্পর্কে আরও শেখার জন্য আমার ক্ষুধা বাড়িয়ে তুলতে সহায়তা করে।
উপরোক্ত উত্তরের উত্তরের পাশাপাশি, আমি আপনাকে নীচের নিবন্ধটির একটি লিঙ্ক অফার করি (প্যাট্রিক থমসনের লিখিত) যা জাভাস্ক্রিপ্ট লাইব্রেরি jQuery এর ধারণার সাথে মনডকে ব্যাখ্যা করে (এবং এটি ডিওএমকে পরিচালনা করার জন্য "পদ্ধতি শৃঙ্খলা" ব্যবহারের উপায়) : jQuery একটি Monad হয়
JQuery এর ডকুমেন্টেশন নিজেই "রচয়িতা প্যাটার্ন" যা সম্ভবত আরো পরিচিত সম্পর্কে শব্দ "একসংখ্যা" কিন্তু আলোচনা পড়ুন না। এটি সম্ভবত এটি উপলব্ধি না করেই আপনার উপযুক্ত মোনাদ রয়েছে তা পরিবর্তন করে না।
মনডস রূপক নয় , তবে ড্যানিয়েল স্পিউয়কের ব্যাখ্যা অনুসারে একটি সাধারণ প্যাটার্ন থেকে কার্যকরভাবে কার্যকর বিমূর্ততা উদ্ভূত হয়েছে।
একটি মোনাড হ'ল গণনাগুলি একত্রিত করার একটি উপায় যা একটি সাধারণ প্রসঙ্গে ভাগ করে। এটি পাইপের একটি নেটওয়ার্ক তৈরির মতো। নেটওয়ার্কটি নির্মাণের সময়, এর মাধ্যমে কোনও ডেটা প্রবাহিত হয় না। কিন্তু যখন আমি সমস্ত বিট একসাথে 'বাইন্ড' এবং 'রিটার্ন' দিয়ে পাইকিংয়ের কাজ শেষ করি তখন আমি এর মতো কিছু প্রার্থনা করি runMyMonad monad data
এবং পাইপগুলির মাধ্যমে ডেটা প্রবাহিত হয়।
অনুশীলনে, মোনাড হ'ল ফাংশন কম্পোজিশন অপারেটরের একটি কাস্টম বাস্তবায়ন যা পার্শ্ব প্রতিক্রিয়া এবং বেমানান ইনপুট এবং রিটার্ন মানগুলি (শৃঙ্খলার জন্য) যত্ন করে।
আমি যদি সঠিকভাবে বুঝতে পারি তবে আইনামেবলটি মনড থেকে উদ্ভূত। আমি ভাবছি যদি এটি আমাদের # সি বিশ্ব থেকে তাদের জন্য দৃষ্টিভঙ্গির আকর্ষণীয় কোণ হতে পারে?
এটির মূল্যের জন্য, এখানে টিউটোরিয়ালগুলির কয়েকটি লিঙ্ক রয়েছে যা আমাকে সহায়তা করেছিল (এবং না, আমি এখনও বুঝতে পারি না যে মোনাডগুলি কী)।
দুটি বিষয় যা আমার সম্পর্কে সবচেয়ে ভাল সহায়তা করেছিল সেগুলি সম্পর্কে জানার পরে:
অষ্টম অধ্যায়, হাস্কেলের গ্রাহাম হাটনের বই প্রোগ্রামিংয়ের বই "ফাংশনাল পার্সারস" । এটি মোটেও মনাদদের উল্লেখ করে না, তবে আপনি যদি অধ্যায়টির মাধ্যমে কাজ করতে পারেন এবং এটিতে সমস্ত কিছু বুঝতে পারেন, বিশেষত কীভাবে বাঁধাইয়ের ক্রমগুলির ক্রম মূল্যায়ন করা হয়, আপনি মনডের অভ্যন্তরীণগুলি বুঝতে পারবেন। এটি বেশ কয়েকটি চেষ্টা করবে বলে আশা করি।
টিউটোরিয়াল অল অ্যাট অ্যা মোনডস । এটি তাদের ব্যবহারের বেশ কয়েকটি ভাল উদাহরণ দেয় এবং আমাকে বলতে হবে যে পরিশিষ্টে উপমাটি আমার পক্ষে কাজ করেছিল।
মনোয়েড এমন এক জিনিস হিসাবে উপস্থিত যা নিশ্চিত করে যে কোনও মনোয়েড এবং একটি সমর্থিত ধরণে সংজ্ঞায়িত সমস্ত ক্রিয়াকলাপ সর্বদা মনোয়েডের ভিতরে একটি সমর্থিত প্রকার ফিরে আসবে। উদাহরণস্বরূপ, যে কোনও সংখ্যা + যে কোনও সংখ্যা = একটি সংখ্যা, কোনও ত্রুটি নেই।
বিভাগটি দুটি ভগ্নাংশ গ্রহণ করে এবং একটি ভগ্নাংশ দেয়, যা শূন্য দ্বারা বিভাগকে ইনফিনিটি হিসাবে কিছুটা হ্যাশেল ইনফিনিটি হিসাবে সংজ্ঞায়িত করে (যা কিছুটা ভগ্নাংশ হতে পারে) ...
যাইহোক, এটি প্রদর্শিত হয় যে Mon عملগুলি আপনার ক্রিয়াকলাপটি অনুমানযোগ্য আচরণ করে এবং এটি এমন একটি ফাংশন যা নুম -> নুম বলে দাবি করে, N-- এর আরও একটি ফাংশন যা x- এর সাথে ডাকা হয় না বলুন, ক্ষেপণাস্ত্র গুলি।
অন্যদিকে, যদি আমাদের এমন কোনও ফাংশন থাকে যা ক্ষেপণাস্ত্রগুলিকে আগুন দেয়, তবে আমরা এটি অন্যান্য কার্যক্রমে রচনা করতে পারি যা ক্ষেপণাস্ত্রগুলিকে আগুন দেয়, কারণ আমাদের অভিপ্রায় স্পষ্ট - আমরা মিসাইল গুলি চালাতে চাই - তবে এটি চেষ্টা করবে না কিছু বিজোড় কারণে "হ্যালো ওয়ার্ল্ড" মুদ্রণ করা হচ্ছে।
হাস্কেল-এ প্রধান আইও (), বা আইও [()] টাইপ হয়, বিভক্তিটি অদ্ভুত এবং আমি এটি নিয়ে আলোচনা করব না তবে আমার মনে হয় যা ঘটেছিল তা এখানে:
যদি আমার প্রধান থাকে, আমি এটি ক্রিয়াগুলির একটি শৃঙ্খল করতে চাই, আমি প্রোগ্রামটি চালানোর কারণটি হ'ল একটি প্রভাব তৈরি করে - সাধারণত যদিও আইও। সুতরাং আমি আইও অপারেশনগুলিকে একসাথে চেইন করতে পারি - আইও করুন, অন্য কিছু নয়।
যদি আমি এমন কিছু করার চেষ্টা করি যা "রিটার্ন আইও" না করে তবে প্রোগ্রামটি অভিযোগ করবে যে চেইনটি প্রবাহিত হয় না, বা মূলত "এটি কীভাবে আমরা করার চেষ্টা করছি - একটি আইও অ্যাকশন" এর সাথে সম্পর্কিত, এটি বলপূর্বক বলে মনে হচ্ছে প্রোগ্রামার তাদের ভেবে চিন্তার ট্রেন রাখবে, বিভ্রান্ত না হয়ে এবং মিসাইল গুলি চালানোর কথা চিন্তা না করে, বাছাইয়ের জন্য অ্যালগরিদম তৈরি করার সময় - যা প্রবাহিত হয় না।
মূলত, মনাদস সংকলকের কাছে একটি টিপ বলে মনে হয় যে "আরে, আপনি এই ফাংশনটি জানেন যা এখানে একটি সংখ্যা ফেরত দেয়, এটি আসলে সবসময় কাজ করে না, এটি কখনও কখনও একটি সংখ্যা তৈরি করতে পারে, এবং কখনও কখনও কিছুই না, কেবল এটিকে রাখুন মন "। এটি জানার পরে, যদি আপনি কোনও মোনাডিক পদক্ষেপের প্রতি দৃ to়তার চেষ্টা করেন, তবে মোনাডিক ক্রিয়াটি সংকলনের সময় ব্যতিক্রম হিসাবে কাজ করতে পারে বলে "আরে, এটি আসলে কোনও সংখ্যা নয়, এই সংখ্যাটি হতে পারে, তবে আপনি এটি ধরে নিতে পারবেন না, কিছু করুন প্রবাহটি গ্রহণযোগ্য কিনা তা নিশ্চিত করার জন্য। " যা অপ্রত্যাশিত প্রোগ্রাম আচরণকে বাধা দেয় - যথেষ্ট পরিমাণে।
এটি প্রদর্শিত হয় যে স্নাতক পবিত্রতা বা নিয়ন্ত্রণ সম্পর্কে নয়, তবে এমন একটি বিভাগের একটি পরিচয় বজায় রাখার বিষয়ে যেখানে সমস্ত আচরণ অনুমানযোগ্য এবং সংজ্ঞায়িত হয় বা সংকলন করে না। আপনি যখন কিছু করার আশা করছেন তখন আপনি কিছুই করতে পারবেন না এবং আপনি কিছু না করার (দৃশ্যমান) প্রত্যাশা করা হলে আপনি কিছু করতে পারবেন না।
আমি মোনাডসের জন্য সবচেয়ে বড় কারণটি ভাবতে পারি - হ'ল কার্যবিধি / ওওপি কোডটি দেখুন এবং আপনি খেয়াল করবেন যে আপনি জানেন না যে প্রোগ্রামটি কোথায় শুরু হয়, না শেষ হয়, আপনি যে সমস্ত কিছুই দেখেন তা হ'ল প্রচুর ঝাঁপ দাও এবং প্রচুর গণিত is , যাদু এবং ক্ষেপণাস্ত্র আপনি এটি বজায় রাখতে সক্ষম হবেন না এবং যদি আপনি পারেন তবে এর পুরো অংশটি বোঝার আগে আপনি পুরো প্রোগ্রামটি ঘিরে আপনার মনকে জড়িয়ে রাখার জন্য প্রচুর সময় ব্যয় করবেন, কারণ এই প্রসঙ্গে পরিমিতি পরস্পর নির্ভরশীল "বিভাগগুলি" এর উপর ভিত্তি করে কোডের কোড যেখানে দক্ষতা / আন্তঃ সম্পর্কের প্রতিশ্রুতি হিসাবে কোড যথাসম্ভব সম্পর্কিত হতে অনুকূলিত হয়েছে। মনডগুলি খুব কংক্রিট, এবং সংজ্ঞা দ্বারা ভালভাবে সংজ্ঞায়িত করা হয়েছে এবং এটি নিশ্চিত করা হয়েছে যে প্রোগ্রামের প্রবাহটি বিশ্লেষণ করা সম্ভব, এবং বিশ্লেষণ করা শক্ত এমন অংশগুলি বিচ্ছিন্ন করে দিন - কারণ তারা নিজেরাই মনড। একটি মোনাদ একটি " বা মহাবিশ্বকে ধ্বংস করুন বা সময়কে বিকৃতও করুন - আমাদের ধারণা নেই বা এর কোনও গ্যারান্টি নেই যে এটি আইটি কী। একটি মোনাডা গ্যারান্টি দেয় যে এটি আসলে যা। যা খুব শক্তিশালী। বা মহাবিশ্বকে ধ্বংস করুন বা সময়কে বিকৃতও করুন - আমাদের ধারণা নেই বা এর কোনও গ্যারান্টি নেই যে এটি আইটি কী। একটি মোনাডা গ্যারান্টি দেয় যে এটি আসলে যা। যা খুব শক্তিশালী।
"রিয়েল ওয়ার্ল্ড" এর সমস্ত জিনিসই মনাদ হিসাবে উপস্থিত হয়, এই অর্থে যে এটি বিভ্রান্তি রোধ করে এমন নির্দিষ্ট পর্যবেক্ষণ আইন দ্বারা আবদ্ধ। এর অর্থ এই নয় যে ক্লাস তৈরি করার জন্য আমাদের এই অবজেক্টের সমস্ত ক্রিয়াকলাপ নকল করতে হবে, পরিবর্তে আমরা কেবল "বর্গ একটি বর্গক্ষেত্র" বলতে পারি, একটি বর্গক্ষেত্র ছাড়া কিছুই নয় এমনকি আয়তক্ষেত্র বা বৃত্তও নয়, এবং "একটি বর্গক্ষেত্রের ক্ষেত্রফল রয়েছে এটি বিদ্যমান মাত্রাগুলির একটি দৈর্ঘ্যের সাথে নিজেই বহুগুণ বেড়েছে you আপনার 2 বর্গক্ষেত্রের বর্গক্ষেত্র যাই হোক না কেন, এটির ক্ষেত্রটি সম্পূর্ণরূপে তার দৈর্ঘ্য বর্গক্ষেত্র ছাড়া কিছুই হতে পারে না, এটি প্রমাণ করা প্রায় তুচ্ছ। এটি খুব শক্তিশালী কারণ কারণ আমাদের পৃথিবীটি যেভাবে হয় তা নিশ্চিত করার জন্য আমাদের দৃ as়তা দেওয়ার দরকার নেই, আমরা আমাদের প্রোগ্রামগুলি ট্র্যাক থেকে নিরস্ত করার জন্য কেবল বাস্তবতার নিদর্শনগুলি ব্যবহার করি।
আমি বেশ ভুল হওয়ার গ্যারান্টিযুক্ত কিন্তু আমার মনে হয় এটি এর সাহায্যে কাউকে সাহায্য করতে পারে, তাই আশা করি এটি কারওর পক্ষে সহায়তা করবে।
স্কালার প্রসঙ্গে আপনি নিম্নলিখিতটি সাদামাটা সংজ্ঞা হিসাবে দেখতে পাবেন। মূলত ফ্ল্যাটম্যাপ (বা বাইন্ড) হ'ল 'সহযোগী' এবং এর একটি পরিচয় রয়েছে।
trait M[+A] {
def flatMap[B](f: A => M[B]): M[B] // AKA bind
// Pseudo Meta Code
def isValidMonad: Boolean = {
// for every parameter the following holds
def isAssociativeOn[X, Y, Z](x: M[X], f: X => M[Y], g: Y => M[Z]): Boolean =
x.flatMap(f).flatMap(g) == x.flatMap(f(_).flatMap(g))
// for every parameter X and x, there exists an id
// such that the following holds
def isAnIdentity[X](x: M[X], id: X => M[X]): Boolean =
x.flatMap(id) == x
}
}
যেমন
// These could be any functions
val f: Int => Option[String] = number => if (number == 7) Some("hello") else None
val g: String => Option[Double] = string => Some(3.14)
// Observe these are identical. Since Option is a Monad
// they will always be identical no matter what the functions are
scala> Some(7).flatMap(f).flatMap(g)
res211: Option[Double] = Some(3.14)
scala> Some(7).flatMap(f(_).flatMap(g))
res212: Option[Double] = Some(3.14)
// As Option is a Monad, there exists an identity:
val id: Int => Option[Int] = x => Some(x)
// Observe these are identical
scala> Some(7).flatMap(id)
res213: Option[Int] = Some(7)
scala> Some(7)
res214: Some[Int] = Some(7)
দ্রষ্টব্য কঠোরভাবে ফাংশনাল প্রোগ্রামিংয়ে একটি Monad এর সংজ্ঞা বলতে বিভাগ থিয়োরিতে একটি Monad সংজ্ঞা হিসাবে একই নয় , যা পরিবর্তিত map
এবং flatten
। যদিও তারা নির্দিষ্ট ম্যাপিংয়ের অধীনে এক ধরণের সমতুল্য। এই উপস্থাপনাগুলি খুব ভাল: http://www.slideshare.net/samthemonad/monad-premittedation-scala-as-a-category
এই উত্তরটি একটি অনুপ্রেরণামূলক উদাহরণ দিয়ে শুরু হয়, উদাহরণের মাধ্যমে কাজ করে, একটি মনাদের উদাহরণ গ্রহণ করে এবং "মোনাড" আনুষ্ঠানিকভাবে সংজ্ঞায়িত করে।
সিউডোকোডে এই তিনটি ফাংশন বিবেচনা করুন:
f(<x, messages>) := <x, messages "called f. ">
g(<x, messages>) := <x, messages "called g. ">
wrap(x) := <x, "">
f
ফর্মের একটি অর্ডারযুক্ত জুড়ি নেয় <x, messages>
এবং একটি অর্ডারযুক্ত জোড় দেয়। এটি প্রথম আইটেমটি ছোঁয়াচে ফেলে "called f. "
দেয় এবং দ্বিতীয় আইটেমে সংযোজন করে। একই সাথে g
।
আপনি এই ফাংশনগুলি রচনা করতে পারেন এবং আপনার মূল মানটি পেতে পারেন, সেই সাথে একটি স্ট্রিং যা দেখায় যে ক্রিয়াকলাপগুলিতে ডাকা হয়েছিল তা কী আদেশ:
f(g(wrap(x)))
= f(g(<x, "">))
= f(<x, "called g. ">)
= <x, "called g. called f. ">
আপনি এই সত্যটি অপছন্দ করেন f
এবং g
পূর্ববর্তী লগিং তথ্যে তাদের নিজস্ব লগ বার্তা যুক্ত করার জন্য দায়বদ্ধ। (কেবল যুক্তি দেখানোর জন্য কল্পনা করুন যে স্ট্রিং সংযোজন করার পরিবর্তে f
এবং g
জোড়ের দ্বিতীয় আইটেমটিতে জটিল যুক্তি সম্পাদন করতে হবে that এই জটিল যুক্তিকে দু'এর বেশি - বিভিন্ন ফাংশনে পুনরাবৃত্তি করা ব্যথা হবে।)
আপনি সহজ ফাংশন লিখতে পছন্দ করেন:
f(x) := <x, "called f. ">
g(x) := <x, "called g. ">
wrap(x) := <x, "">
তবে আপনি তাদের রচনা করলে কী ঘটে তা দেখুন:
f(g(wrap(x)))
= f(g(<x, "">))
= f(<<x, "">, "called g. ">)
= <<<x, "">, "called g. ">, "called f. ">
সমস্যাটি হ'ল কোনও ফাংশনে একটি জুড়ি পাস করা আপনাকে যা চান তা দেয় না। তবে আপনি যদি কোনও ফাংশনে কোনও জুড়ি খাওয়াতে পারেন তবে :
feed(f, feed(g, wrap(x)))
= feed(f, feed(g, <x, "">))
= feed(f, <x, "called g. ">)
= <x, "called g. called f. ">
feed(f, m)
"ফিড m
ইন f
" হিসাবে পড়ুন । করার ভোজন একজোড়া <x, messages>
একটি ফাংশন মধ্যে f
হয় পাস x
মধ্যে f
পেতে <y, message>
আউট f
, এবং আসতে <y, messages message>
।
feed(f, <x, messages>) := let <y, message> = f(x)
in <y, messages message>
আপনি যখন আপনার ফাংশন দিয়ে তিনটি জিনিস করেন তখন কী ঘটে তা লক্ষ্য করুন:
প্রথম: আপনি যদি কোনও মান আবদ্ধ করেন এবং তারপরে ফলাফলটি জোড়াটি কোনও ফাংশনে খাওয়ান :
feed(f, wrap(x))
= feed(f, <x, "">)
= let <y, message> = f(x)
in <y, "" message>
= let <y, message> = <x, "called f. ">
in <y, "" message>
= <x, "" "called f. ">
= <x, "called f. ">
= f(x)
এটি ফাংশনে মান পাস করার সমান ।
দ্বিতীয়: আপনি যদি একটি জুটিকে খাওয়ান wrap
:
feed(wrap, <x, messages>)
= let <y, message> = wrap(x)
in <y, messages message>
= let <y, message> = <x, "">
in <y, messages message>
= <x, messages "">
= <x, messages>
এতে জুটি বদলায় না।
তৃতীয়: আপনি যদি কোনও ক্রিয়া সংজ্ঞায়িত করেন যা এতে গ্রহণ করে x
এবং ফিড g(x)
দেয় f
:
h(x) := feed(f, g(x))
এবং এতে একটি জোড়া খাওয়ান:
feed(h, <x, messages>)
= let <y, message> = h(x)
in <y, messages message>
= let <y, message> = feed(f, g(x))
in <y, messages message>
= let <y, message> = feed(f, <x, "called g. ">)
in <y, messages message>
= let <y, message> = let <z, msg> = f(x)
in <z, "called g. " msg>
in <y, messages message>
= let <y, message> = let <z, msg> = <x, "called f. ">
in <z, "called g. " msg>
in <y, messages message>
= let <y, message> = <x, "called g. " "called f. ">
in <y, messages message>
= <x, messages "called g. " "called f. ">
= feed(f, <x, messages "called g. ">)
= feed(f, feed(g, <x, messages>))
এটি জুটিকে g
খাওয়ানো এবং ফলস্বরূপ জুটিকে খাওয়ানো সমান f
।
আপনার কাছে বেশিরভাগ মোনাড রয়েছে। আপনার প্রোগ্রামে থাকা ডেটা ধরণের সম্পর্কে এখন আপনার জানা দরকার।
মান কত প্রকার <x, "called f. ">
? ঠিক আছে, এটি নির্ভর করে কোন ধরণের মান x
। যদি x
টাইপ হয় t
তবে আপনার জুড়িটি "জোড়া t
এবং স্ট্রিং" টাইপের মান type টাইপ কল M t
।
M
এটি একটি টাইপ কনস্ট্রাক্টর: M
এককভাবে কোনও প্রকারকে বোঝায় না, তবে M _
একবার আপনি টাইপের সাথে শূন্যস্থান পূরণ করার পরে কোনও প্রকারকে বোঝায়। একটি M int
হ'ল একটি আন্ত এবং স্ট্রিংয়ের জুড়ি। আন M string
একটি স্ট্রিং এবং স্ট্রিংয়ের একটি জুড়ি। প্রভৃতি
অভিনন্দন, আপনি একটি monad তৈরি করেছেন!
সাধারণত, আপনার মোনাড টিপল <M, feed, wrap>
।
একটি মোনাদ একটি টুপল <M, feed, wrap>
যেখানে:
M
একটি টাইপ কনস্ট্রাক্টর।feed
একটি গ্রহণ করে (একটি ফাংশন যা একটি নেয় t
এবং ফেরত দেয় M u
) এবং একটি M t
এবং একটি প্রদান করে M u
।wrap
একটি নেয় v
এবং একটি প্রদান করে M v
।t
, u
এবং v
এই তিনটি ধরণের যা একই বা নাও হতে পারে। একটি মোনাড আপনার নির্দিষ্ট মোনাডের জন্য প্রমাণিত তিনটি সম্পত্তি সন্তুষ্ট করে:
t
কোনও ফাংশনে মোড়ক খাওয়ানো ফাংশনে আবদ্ধ হওয়া পাস করার সমান t
।
আনুষ্ঠানিকভাবে: feed(f, wrap(x)) = f(x)
একটি খাওয়ানো M t
মধ্যে wrap
কিছুই না M t
।
আনুষ্ঠানিকভাবে: feed(wrap, m) = m
একটি ফাংশন একটি M t
(এটি কল m
) খাওয়ানো যে
t
মধ্যেg
M u
(এটি কল n
) পায়g
n
মধ্যেf
হিসাবে একই
m
মধ্যেg
n
থেকে পেয়েg
n
মধ্যেf
আনুষ্ঠানিকভাবে: feed(h, m) = feed(f, feed(g, m))
যেখানেh(x) := feed(f, g(x))
সাধারণত, feed
বলা হয় bind
( >>=
হাস্কেল ইন wrap
একে ) এবং বলা হয় return
।
আমি Monad
হাস্কেলের প্রসঙ্গে ব্যাখ্যা করার চেষ্টা করব ।
ফাংশনাল প্রোগ্রামিংয়ে, ফাংশন কম্পোজিশন গুরুত্বপূর্ণ। এটি আমাদের প্রোগ্রামকে ছোট, সহজেই পঠনযোগ্য ফাংশনগুলি সমন্বিত করতে সহায়তা করে।
ধরা যাক আমাদের দুটি ফাংশন রয়েছে: g :: Int -> String
এবং f :: String -> Bool
।
আমরা করতে পারি (f . g) x
, যা কেবল একই f (g x)
, যেখানে x
একটি Int
মান।
রচনাটি করার সময় / এক ফাংশনের ফলাফলটিকে অন্যটিতে প্রয়োগ করার সময়, ধরণগুলি মিলে যাওয়া গুরুত্বপূর্ণ। উপরের ক্ষেত্রে, ফলাফলের ধরণটি যে ধাপে ফিরে এসেছে তা g
অবশ্যই গ্রহণযোগ্য প্রকারের মতই হতে হবে f
।
তবে কখনও কখনও মানগুলি প্রসঙ্গে থাকে এবং এটি ধরণের লাইনে কিছুটা সহজ করে তোলে। (প্রেক্ষিতে মান রয়ে খুবই দরকারী। উদাহরণস্বরূপ, Maybe Int
টাইপ একটি প্রতিনিধিত্ব করে Int
মান যে নাও হতে পারে, IO String
ধরনের একটি প্রতিনিধিত্ব করে String
আছে যে কিছু পার্শ্ব প্রতিক্রিয়া করণ ফলে মান।)
ধরা যাক আমাদের এখন আছে g1 :: Int -> Maybe String
এবং f1 :: String -> Maybe Bool
। g1
এবং যথাক্রমে এবং f1
খুব মিল ।g
f
আমরা করতে পারি না (f1 . g1) x
বা f1 (g1 x)
, যেখানে x
একটি Int
মান। ফলাফল g1
কী ধরণের f1
প্রত্যাশিত তা প্রত্যাশা করে না ।
আমরা রচনা করতে পারে f
এবং g
সঙ্গে .
অপারেটর, কিন্তু এখন আমরা রচনা করতে পারবে না f1
এবং g1
সঙ্গে .
। সমস্যাটি হ'ল আমরা কোনও প্রসঙ্গে কোনও প্রসঙ্গে যা কোনও প্রসঙ্গের মধ্যে নয় এমন একটি মান প্রত্যাশা করে তা স্পষ্টভাবে কোনও প্রসঙ্গে একটি মান প্রেরণ করতে পারি না।
আমরা যদি কোনও অপারেটরকে রচনা করার জন্য g1
এবং এমনটি f1
লিখতে (f1 OPERATOR g1) x
পারি যে পরিচয় করিয়ে দেওয়া ভাল হয় না ? g1
একটি প্রসঙ্গে একটি মান প্রদান করে। মানটি প্রসঙ্গের বাইরে নেওয়া হবে এবং এতে প্রয়োগ করা হবে f1
। এবং হ্যাঁ, আমাদের এমন অপারেটর রয়েছে। এটা <=<
।
আমাদের কাছে >>=
অপারেটরও রয়েছে যা আমাদের জন্য ঠিক একই জিনিসটি করে, যদিও কিছুটা আলাদা সিনট্যাক্সে।
আমরা লিখুন: g1 x >>= f1
। g1 x
একটি Maybe Int
মান। >>=
অপারেটর যে নিতে সাহায্য করে Int
"সম্ভবত নয়-সেখানে" প্রসঙ্গের বাইরে মান, এবং এটি প্রয়োগ f1
। এর ফলাফল f1
, যা একটি Maybe Bool
, সম্পূর্ণ >>=
ক্রিয়াকলাপের ফলাফল হবে ।
এবং অবশেষে, কেন Monad
দরকারী? কারণ Monad
টাইপ বর্গ সংজ্ঞায়িত যে >>=
অপারেটর, খুব একই হিসাবে Eq
টাইপ বর্গ যে সংজ্ঞায়িত ==
এবং /=
অপারেটর।
উপসংহারে, Monad
প্রকারের শ্রেণিটি >>=
অপারেটরটিকে সংজ্ঞায়িত করে যা আমাদের একটি প্রসঙ্গে মানগুলি পাস করার অনুমতি দেয় (আমরা এই monadic মানগুলি কল করি) এমন কোনও ফাংশনে যা কোনও প্রসঙ্গে মানগুলি প্রত্যাশা করে না। প্রসঙ্গে যত্ন নেওয়া হবে।
এখানে যদি মনে রাখার মতো একটি জিনিস থাকে তবে এটি হ'ল প্রাসঙ্গিক Monad
মানগুলিতে জড়িত ফাংশন রচনার অনুমতি দিন ।
{-# LANGUAGE InstanceSigs #-}
newtype Id t = Id t
instance Monad Id where
return :: t -> Id t
return = Id
(=<<) :: (a -> Id b) -> Id a -> Id b
f =<< (Id x) = f x
$
ফাংশনগুলির অ্যাপ্লিকেশন অপারেটর
forall a b. a -> b
সাধারণভাবে সংজ্ঞায়িত করা হয়
($) :: (a -> b) -> a -> b
f $ x = f x
infixr 0 $
হাস্কেল-আদিম ফাংশন অ্যাপ্লিকেশন f x
( infixl 10
) এর ক্ষেত্রে।
রচনাটি হিসাবে হিসাবে .
সংজ্ঞায়িত করা হয়$
(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = \ x -> f $ g x
infixr 9 .
এবং সমতা সন্তুষ্ট forall f g h.
f . id = f :: c -> d Right identity
id . g = g :: b -> c Left identity
(f . g) . h = f . (g . h) :: a -> d Associativity
.
সাহসী এবং id
এটি ডান এবং বাম পরিচয়।
প্রোগ্রামিংয়ে একটি মোনাড হ'ল ফান্টেক্টর টাইপ কনস্ট্রাক্টর যার সাথে মোনাদ টাইপ শ্রেণীর উদাহরণ থাকে। সংজ্ঞা এবং বাস্তবায়নের বেশ কয়েকটি সমতুল্য রূপ রয়েছে, প্রতিটি মনড বিমূর্ততা সম্পর্কে কিছুটা ভিন্ন স্বজ্ঞাত বহন করে।
একজন functor একটি টাইপ কন্সট্রাকটর হয় f
ধরনের * -> *
functor টাইপ ক্লাসের একটা নিদর্শন রয়েছে।
{-# LANGUAGE KindSignatures #-}
class Functor (f :: * -> *) where
map :: (a -> b) -> (f a -> f b)
স্ট্যাটিকালি প্রয়োগ করা টাইপ প্রোটোকল অনুসরণ করার পাশাপাশি, ফান্টকার টাইপ শ্রেণীর উদাহরণগুলি অবশ্যই বীজগণিতীয় ফান্টারের আইন মেনে চলতে হবে forall f g.
map id = id :: f t -> f t Identity
map f . map g = map (f . g) :: f a -> f c Composition / short cut fusion
ফ্যাক্টর গণনা টাইপ আছে
forall f t. Functor f => f t
একটি গুনতি c r
মধ্যে রয়েছে ফল r
মধ্যে প্রেক্ষাপটে c
।
ইউনিারি মোনাডিক ফাংশন বা ক্লাইসলি তীরগুলির টাইপ রয়েছে
forall m a b. Functor m => a -> m b
ক্লাইসি তীরগুলি হ'ল ফাংশন যা একটি যুক্তি গ্রহণ করে a
এবং এক একক গণনা ফিরিয়ে দেয় m b
।
মনাদাসমূহ ক্লিসলি ট্রিপল এর পরিভাষায় স্বতন্ত্রভাবে সংজ্ঞায়িত করা হয় forall m. Functor m =>
(m, return, (=<<))
টাইপ ক্লাস হিসাবে বাস্তবায়িত
class Functor m => Monad m where
return :: t -> m t
(=<<) :: (a -> m b) -> m a -> m b
infixr 1 =<<
Kleisli পরিচয় return
একটি Kleisli তীর যে একটি মান প্রচার করে t
কীটাণুজাতীয় প্রসঙ্গ মধ্যে m
। এক্সটেনশন বা ক্লাইসলি অ্যাপ্লিকেশন কোনও গণনার ফলাফলের জন্য =<<
ক্লেস্লি তীর প্রয়োগ করে ।a -> m b
m a
Kleisli রচনাটি <=<
এক্সটেনশনের ক্ষেত্রে সংজ্ঞায়িত করা হয়
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = \ x -> f =<< g x
infixr 1 <=<
<=<
ডান তীর প্রয়োগের ফলাফলের জন্য বাম তীর প্রয়োগ করে দুটি ক্লেসলি তীর রচনা করে।
মোনাড ধরণের শ্রেণীর উদাহরণগুলিতে অবশ্যই মোনাদ আইন মানতে হবে , সবচেয়ে সুন্দরভাবে ক্লাইসলি রচনার ক্ষেত্রে বলা হয়েছে:forall f g h.
f <=< return = f :: c -> m d Right identity
return <=< g = g :: b -> m c Left identity
(f <=< g) <=< h = f <=< (g <=< h) :: a -> m d Associativity
<=<
সাহসী এবং return
এটি ডান এবং বাম পরিচয়।
পরিচয়ের ধরণ
type Id t = t
প্রকারভেদে পরিচয় ফাংশন
Id :: * -> *
ফান্টেক্টর হিসাবে ব্যাখ্যা করা,
return :: t -> Id t
= id :: t -> t
(=<<) :: (a -> Id b) -> Id a -> Id b
= ($) :: (a -> b) -> a -> b
(<=<) :: (b -> Id c) -> (a -> Id b) -> (a -> Id c)
= (.) :: (b -> c) -> (a -> b) -> (a -> c)
ক্যানোনিকাল হাস্কেলে, পরিচয় মনড সংজ্ঞায়িত করা হয়
newtype Id t = Id t
instance Functor Id where
map :: (a -> b) -> Id a -> Id b
map f (Id x) = Id (f x)
instance Monad Id where
return :: t -> Id t
return = Id
(=<<) :: (a -> Id b) -> Id a -> Id b
f =<< (Id x) = f x
একটি বিকল্প প্রকার
data Maybe t = Nothing | Just t
এনকোড গণনা Maybe t
যা অগত্যা কোনও ফলাফল দেয় না t
, এমন গণনা যা "ব্যর্থ" হতে পারে। বিকল্প monad সংজ্ঞায়িত করা হয়
instance Functor Maybe where
map :: (a -> b) -> (Maybe a -> Maybe b)
map f (Just x) = Just (f x)
map _ Nothing = Nothing
instance Monad Maybe where
return :: t -> Maybe t
return = Just
(=<<) :: (a -> Maybe b) -> Maybe a -> Maybe b
f =<< (Just x) = f x
_ =<< Nothing = Nothing
a -> Maybe b
কোনও ফলাফলের জন্য কেবল তখনই প্রয়োগ করা হয় যদি Maybe a
ফলাফল আসে।
newtype Nat = Nat Int
প্রাকৃতিক সংখ্যাগুলি শূন্যের চেয়ে বৃহত্তর বা সমান হিসাবে পূর্ণসংখ্যা হিসাবে এনকোড করা যায়।
toNat :: Int -> Maybe Nat
toNat i | i >= 0 = Just (Nat i)
| otherwise = Nothing
বিয়োগের অধীনে প্রাকৃতিক সংখ্যাগুলি বন্ধ হয় না।
(-?) :: Nat -> Nat -> Maybe Nat
(Nat n) -? (Nat m) = toNat (n - m)
infixl 6 -?
বিকল্প মোনাড ব্যতিক্রম হ্যান্ডলিংয়ের একটি প্রাথমিক ফর্মটি জুড়ে।
(-? 20) <=< toNat :: Int -> Maybe Nat
তালিকার প্রকারের উপরে তালিকা মোনাড
data [] t = [] | t : [t]
infixr 5 :
এবং এর যোগমূলক মনোয়েড অপারেশন "সংযোজন"
(++) :: [t] -> [t] -> [t]
(x : xs) ++ ys = x : xs ++ ys
[] ++ ys = ys
infixr 5 ++
প্রাকৃতিক পরিমাণে ফলাফল দেয় ননলাইনার গণনা এনকোড করে ।[t]
0, 1, ...
t
instance Functor [] where
map :: (a -> b) -> ([a] -> [b])
map f (x : xs) = f x : map f xs
map _ [] = []
instance Monad [] where
return :: t -> [t]
return = (: [])
(=<<) :: (a -> [b]) -> [a] -> [b]
f =<< (x : xs) = f x ++ (f =<< xs)
_ =<< [] = []
এক্সটেনশন =<<
concatenates ++
সমস্ত তালিকা [b]
অ্যাপ্লিকেশনের ফলে f x
একটি Kleisli এর তীর a -> [b]
এর উপাদান [a]
একক কোনো ফলাফল তালিকায় [b]
।
ধনাত্মক পূর্ণসংখ্যার যথাযথ বিভাজনগুলি n
হতে দিন
divisors :: Integral t => t -> [t]
divisors n = filter (`divides` n) [2 .. n - 1]
divides :: Integral t => t -> t -> Bool
(`divides` n) = (== 0) . (n `rem`)
তারপর
forall n. let { f = f <=< divisors } in f n = []
মোনাড প্রকারের শ্রেণীর সংজ্ঞা দেওয়ার ক্ষেত্রে, এক্সটেনশনের পরিবর্তে =<<
, হাস্কেল স্ট্যান্ডার্ডটি তার ফ্লিপ ব্যবহার করে, বাইন্ড অপারেটর >>=
।
class Applicative m => Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
(>>) :: forall a b. m a -> m b -> m b
m >> k = m >>= \ _ -> k
{-# INLINE (>>) #-}
return :: a -> m a
return = pure
সরলতার জন্য, এই ব্যাখ্যাটি শ্রেণীর শ্রেণিবিন্যাসকে ব্যবহার করে
class Functor f
class Functor m => Monad m
হাসকেলে, বর্তমান মানক শ্রেণিবদ্ধতা
class Functor f
class Functor p => Applicative p
class Applicative m => Monad m
কারণ প্রতিটি মোনাদই কেবল ফান্টেক্টর নয়, প্রতিটি আবেদনকারীই একটি ফান্টেক্টর এবং প্রতিটি মনাদ একটি আবেদনকারীও।
তালিকা monad ব্যবহার করে, আবশ্যক সিউডোকোড
for a in (1, ..., 10)
for b in (1, ..., 10)
p <- a * b
if even(p)
yield p
মোটামুটি ডু ব্লকে অনুবাদ করে ,
do a <- [1 .. 10]
b <- [1 .. 10]
let p = a * b
guard (even p)
return p
সমতুল্য মনড বোধগম্যতা ,
[ p | a <- [1 .. 10], b <- [1 .. 10], let p = a * b, even p ]
এবং অভিব্যক্তি
[1 .. 10] >>= (\ a ->
[1 .. 10] >>= (\ b ->
let p = a * b in
guard (even p) >> -- [ () | even p ] >>
return p
)
)
স্বরলিপি এবং মনাদ বোঝাপড়া নেস্টেড বাইন্ড এক্সপ্রেশনগুলির জন্য সিনট্যাকটিক চিনি। বাইন্ড অপারেটর স্থানীয় নাম বাঁধার জন্য monadic ফলাফল ব্যবহার করা হয়।
let x = v in e = (\ x -> e) $ v = v & (\ x -> e)
do { r <- m; c } = (\ r -> c) =<< m = m >>= (\ r -> c)
কোথায়
(&) :: a -> (a -> b) -> b
(&) = flip ($)
infixl 0 &
গার্ড ফাংশন সংজ্ঞায়িত করা হয়
guard :: Additive m => Bool -> m ()
guard True = return ()
guard False = fail
যেখানে ইউনিট টাইপ বা "খালি tuple"
data () = ()
সংযোজনীয় মনডগুলি যা পছন্দ এবং ব্যর্থতা সমর্থন করে কোনও প্রকার শ্রেণীর সাহায্যে বিমূর্ত করা যেতে পারে
class Monad m => Additive m where
fail :: m t
(<|>) :: m t -> m t -> m t
infixl 3 <|>
instance Additive Maybe where
fail = Nothing
Nothing <|> m = m
m <|> _ = m
instance Additive [] where
fail = []
(<|>) = (++)
যেখানে fail
এবং <|>
একটি monoid গঠনforall k l m.
k <|> fail = k
fail <|> l = l
(k <|> l) <|> m = k <|> (l <|> m)
এবং fail
এটি অ্যাডিটিভ মনডগুলির শোষক / ধ্বংসকারী শূন্য উপাদান
_ =<< fail = fail
যদি থাকে
guard (even p) >> return p
even p
সত্য, এরপরে গার্ড স্থানীয় ধ্রুবক ক্রিয়াকলাপের [()]
সংজ্ঞা অনুসারে উত্পাদন করে এবং>>
\ _ -> return p
ফলাফল প্রয়োগ করা হয় ()
। যদি মিথ্যা হয়ে থাকে, তবে রক্ষী তালিকাটি মোনাদের fail
( []
) তৈরি করে , যা ক্লাইসলি তীর প্রয়োগের জন্য কোনও ফল দেয় না >>
, তাই p
এটি বাদ দেওয়া হয়।
দুর্নীতিগ্রস্থভাবে, মনডগুলি রাষ্ট্রীয় গণনা এনকোড করতে ব্যবহৃত হয়।
একটি রাষ্ট্র প্রসেসর একটি ফাংশন
forall st t. st -> (t, st)
যা একটি রাষ্ট্রকে রূপান্তর করে st
এবং ফলাফল দেয় t
। রাষ্ট্র st
কিছু হতে পারে। কিছুই, পতাকা, গণনা, অ্যারে, হ্যান্ডেল, মেশিন, বিশ্ব।
স্টেট প্রসেসরের ধরণকে সাধারণত বলা হয়
type State st t = st -> (t, st)
রাষ্ট্র প্রসেসর একসংখ্যা kinded হয় * -> *
functor State st
। রাজ্যের প্রসেসর মোনাডের ক্লাইসলি তীরগুলি ফাংশন
forall st a b. a -> (State st) b
ক্যানোনিকাল হাস্কেল-এ, রাজ্য প্রসেসর মোনাডের অলস সংস্করণটি সংজ্ঞায়িত করা হয়েছে
newtype State st t = State { stateProc :: st -> (t, st) }
instance Functor (State st) where
map :: (a -> b) -> ((State st) a -> (State st) b)
map f (State p) = State $ \ s0 -> let (x, s1) = p s0
in (f x, s1)
instance Monad (State st) where
return :: t -> (State st) t
return x = State $ \ s -> (x, s)
(=<<) :: (a -> (State st) b) -> (State st) a -> (State st) b
f =<< (State p) = State $ \ s0 -> let (x, s1) = p s0
in stateProc (f x) s1
একটি রাষ্ট্র প্রসেসর একটি প্রাথমিক রাষ্ট্র সরবরাহ করে পরিচালিত হয়:
run :: State st t -> st -> (t, st)
run = stateProc
eval :: State st t -> st -> t
eval = fst . run
exec :: State st t -> st -> st
exec = snd . run
রাজ্য এক্সেস প্রিমিটিভের দ্বারা প্রদান করা হয় get
এবং put
, ওভার বিমূর্ততা পদ্ধতি stateful monads:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
class Monad m => Stateful m st | m -> st where
get :: m st
put :: st -> m ()
m -> st
মোনাডে রাষ্ট্রের ধরণের কার্যকরী নির্ভরতা ঘোষণা করে ; এটি একটি , উদাহরণস্বরূপ, রাষ্ট্রের ধরণকে অনন্যভাবে নির্ধারণ করবে ।st
m
State t
t
instance Stateful (State st) st where
get :: State st st
get = State $ \ s -> (s, s)
put :: st -> State st ()
put s = State $ \ _ -> ((), s)
ইউনিট প্রকারের সাথে void
সি তে অ্যানালগ্যালি ব্যবহৃত হয় with
modify :: Stateful m st => (st -> st) -> m ()
modify f = do
s <- get
put (f s)
gets :: Stateful m st => (st -> t) -> m t
gets f = do
s <- get
return (f s)
gets
প্রায়শই রেকর্ড ক্ষেত্র অ্যাক্সেসরগুলির সাথে ব্যবহৃত হয়।
পরিবর্তনশীল থ্রেডিংয়ের সমতুল্য রাষ্ট্র মোনাড
let s0 = 34
s1 = (+ 1) s0
n = (* 12) s1
s2 = (+ 7) s1
in (show n, s2)
যেখানে s0 :: Int
, সমানভাবে উল্লেখযোগ্যভাবে স্বচ্ছ, তবে অসীমভাবে আরও মার্জিত এবং ব্যবহারিক
(flip run) 34
(do
modify (+ 1)
n <- gets (* 12)
modify (+ 7)
return (show n)
)
modify (+ 1)
ধরনের গণনার হয় State Int ()
তার ব্যতিক্রম হল প্রভাব সমতুল্য return ()
।
(flip run) 34
(modify (+ 1) >>
gets (* 12) >>= (\ n ->
modify (+ 7) >>
return (show n)
)
)
সাহিত্যের মোনাড আইন অনুসারে লেখা যেতে পারে >>=
forall m f g.
(m >>= f) >>= g = m >>= (\ x -> f x >>= g)
অথবা
do { do { do {
r1 <- do { x <- m; r0 <- m;
r0 <- m; = do { = r1 <- f r0;
f r0 r1 <- f x; g r1
}; g r1 }
g r1 }
} }
এক্সপ্রেশন-ওরিয়েন্টেড প্রোগ্রামিংয়ের মতো (যেমন মরিচা), কোনও ব্লকের শেষ বিবৃতিটি তার ফলনকে উপস্থাপন করে। বাইন্ড অপারেটরটিকে কখনও কখনও "প্রোগ্রামেবল সেমিকোলন" বলা হয়।
কাঠামোগত আবশ্যক প্রোগ্রামিং থেকে আইট্রেশন কন্ট্রোল স্ট্রাকচার আদিমগুলি এককভাবে অনুকরণ করা হয়
for :: Monad m => (a -> m b) -> [a] -> m ()
for f = foldr ((>>) . f) (return ())
while :: Monad m => m Bool -> m t -> m ()
while c m = do
b <- c
if b then m >> while c m
else return ()
forever :: Monad m => m t
forever m = m >> forever m
data World
আই / ও ওয়ার্ল্ড স্টেট প্রসেসর মোনাড হ'ল খাঁটি হাস্কেল এবং বাস্তব জগতের ফাংশনাল ডেনোটেটিভ এবং অপরিহার্য অপারেশনাল সিনটিক্সের মিলন। প্রকৃত কঠোর বাস্তবায়নের ঘনিষ্ঠ অ্যানালগ:
type IO t = World -> (t, World)
মিথস্ক্রিয়া অপরিষ্কার আদিম দ্বারা সহজতর হয়
getChar :: IO Char
putChar :: Char -> IO ()
readFile :: FilePath -> IO String
writeFile :: FilePath -> String -> IO ()
hSetBuffering :: Handle -> BufferMode -> IO ()
hTell :: Handle -> IO Integer
. . . . . .
কোডের IO
অপরিষ্কারতা যা আদিম ব্যবহার করে তা স্থায়ীভাবে টাইপ সিস্টেমের দ্বারা প্রোটোকলাইজ করা হয়। কারণ বিশুদ্ধতা দুর্দান্ত, যা ঘটে তা ভিতরে IO
থাকে IO
।
unsafePerformIO :: IO t -> t
বা, কমপক্ষে, উচিত।
একটি হাসকল প্রোগ্রামের স্বাক্ষর
main :: IO ()
main = putStrLn "Hello, World!"
প্রসারিত হয়
World -> ((), World)
এমন একটি ফাংশন যা একটি বিশ্বকে রূপান্তরিত করে।
বিভাগ whiches বস্তু Haskell, ধরনের এবং whiches morphisms Haskell, ধরনের, "দ্রুত এবং আলগা", বিভাগ মধ্যে ফাংশন হয় Hask
।
একজন functor T
একটি বিভাগ থেকে একটি ম্যাপিং হয় C
একটি বিভাগ থেকে D
; মধ্যে C
একটি বস্তুর প্রতিটি বস্তুর জন্যD
Tobj : Obj(C) -> Obj(D)
f :: * -> *
এবং প্রতিটি আকারের জন্য C
একটি আকারে mD
Tmor : HomC(X, Y) -> HomD(Tobj(X), Tobj(Y))
map :: (a -> b) -> (f a -> f b)
যেখানে X
, Y
জিনিস আছে C
। HomC(X, Y)
হয় homomorphism বর্গ সব morphisms এর X -> Y
মধ্যে C
। ফান্টারের অবশ্যই মরফিজম পরিচয় এবং রচনা সংরক্ষণ করতে হবে, এর "কাঠামো" এর C
মধ্যে D
।
Tmor Tobj
T(id) = id : T(X) -> T(X) Identity
T(f) . T(g) = T(f . g) : T(X) -> T(Z) Composition
Kleisli বিভাগ একটি বিভাগ এর C
একটি Kleisli ট্রিপল দেওয়া হয়
<T, eta, _*>
একটি endofunctor এর
T : C -> C
( f
), একটি পরিচয় আকার eta
( return
) এবং একটি এক্সটেনশন অপারেটর *
( =<<
)।
প্রতিটি ক্লাইসলি মরফিজম ইন Hask
f : X -> T(Y)
f :: a -> m b
এক্সটেনশন অপারেটর দ্বারা
(_)* : Hom(X, T(Y)) -> Hom(T(X), T(Y))
(=<<) :: (a -> m b) -> (m a -> m b)
Hask
এর ক্লাইসলি বিভাগে একটি আকার দেওয়া হয়
f* : T(X) -> T(Y)
(f =<<) :: m a -> m b
ক্লাইসলি বিভাগে রচনাটি .T
এক্সটেনশনের ক্ষেত্রে দেওয়া হয়
f .T g = f* . g : X -> T(Z)
f <=< g = (f =<<) . g :: a -> m c
এবং বিভাগের অক্ষগুলিকে সন্তুষ্ট করে
eta .T g = g : Y -> T(Z) Left identity
return <=< g = g :: b -> m c
f .T eta = f : Z -> T(U) Right identity
f <=< return = f :: c -> m d
(f .T g) .T h = f .T (g .T h) : X -> T(U) Associativity
(f <=< g) <=< h = f <=< (g <=< h) :: a -> m d
যা সমতুল্য রূপান্তর প্রয়োগ করে
eta .T g = g
eta* . g = g By definition of .T
eta* . g = id . g forall f. id . f = f
eta* = id forall f g h. f . h = g . h ==> f = g
(f .T g) .T h = f .T (g .T h)
(f* . g)* . h = f* . (g* . h) By definition of .T
(f* . g)* . h = f* . g* . h . is associative
(f* . g)* = f* . g* forall f g h. f . h = g . h ==> f = g
এক্সটেনশনের শর্তাবলী নীতিগতভাবে দেওয়া হয়
eta* = id : T(X) -> T(X) Left identity
(return =<<) = id :: m t -> m t
f* . eta = f : Z -> T(U) Right identity
(f =<<) . return = f :: c -> m d
(f* . g)* = f* . g* : T(X) -> T(Z) Associativity
(((f =<<) . g) =<<) = (f =<<) . (g =<<) :: m a -> m c
মনডসকে ক্লাইস্লিয়ান এক্সটেনশনের ক্ষেত্রে নয়, তবে mu
প্রোগ্রামিংয়ে প্রাকৃতিক রূপান্তর হিসাবেও সংজ্ঞায়িত করা যায় join
। একজন একসংখ্যা পরিপ্রেক্ষিতে সংজ্ঞায়িত করা হয় mu
একটি বিভাগ উপর একটি ট্রিপল যেমন C
একটি endofunctor এর
T : C -> C
f :: * -> *
এবং দুটি প্রাকৃতিক ট্রান্সফর্মেশন
eta : Id -> T
return :: t -> f t
mu : T . T -> T
join :: f (f t) -> f t
সমতা সন্তুষ্ট
mu . T(mu) = mu . mu : T . T . T -> T . T Associativity
join . map join = join . join :: f (f (f t)) -> f t
mu . T(eta) = mu . eta = id : T -> T Identity
join . map return = join . return = id :: f t -> f t
মোনাড টাইপ শ্রেণিটি তখন সংজ্ঞায়িত হয়
class Functor m => Monad m where
return :: t -> m t
join :: m (m t) -> m t
mu
বিকল্পটি মোনাডের ক্যানোনিকাল বাস্তবায়ন:
instance Monad Maybe where
return = Just
join (Just m) = m
join Nothing = Nothing
concat
ক্রিয়া
concat :: [[a]] -> [a]
concat (x : xs) = x ++ concat xs
concat [] = []
হয় join
তালিকা একসংখ্যা করুন।
instance Monad [] where
return :: t -> [t]
return = (: [])
(=<<) :: (a -> [b]) -> ([a] -> [b])
(f =<<) = concat . map f
এর বাস্তবায়নের join
সমানতা এক্সটেনশানটি ব্যবহার করে ফর্ম থেকে অনুবাদ করা যায়
mu = id* : T . T -> T
join = (id =<<) :: m (m t) -> m t
mu
এক্সটেনশন ফর্ম থেকে বিপরীত অনুবাদ দ্বারা দেওয়া হয়
f* = mu . T(f) : T(X) -> T(Y)
(f =<<) = join . map f :: m a -> m b
ফিলিপ ওয়েদার: ফাংশনাল প্রোগ্রামিংয়ের জন্য মনডস
সাইমন এল পিটন জোন্স, ফিলিপ ওয়েডলার: অত্যাবশ্যকীয় ফাংশনাল প্রোগ্রামিং
জোনাথন এমডি হিল, কিথ ক্লার্ক: বিভাগের তত্ত্ব, বিভাগের তত্ত্বের মনড এবং কার্যকরী প্রোগ্রামিংয়ের সাথে তাদের সম্পর্কের পরিচিতি ´
ইউজিনিও মোগগি: গণনা এবং স্নাতকের ধারণা
তবে কেন একটি তত্ত্ব এত বিমূর্তের প্রোগ্রামিংয়ের জন্য কোনও উপযোগী হওয়া উচিত?
উত্তরটি সহজ: কম্পিউটার বিজ্ঞানী হিসাবে, আমরা বিমূর্তির মূল্য ! যখন আমরা কোনও সফ্টওয়্যার উপাদানটিতে ইন্টারফেসটি ডিজাইন করি, আমরা এটি বাস্তবায়ন সম্পর্কে যতটা সম্ভব কম তা প্রকাশ করতে চাই । আমরা বাস্তবের অনেকগুলি বিকল্প, একই 'ধারণার' অনেকগুলি 'উদাহরণ' দিয়ে প্রতিস্থাপন করতে সক্ষম হতে চাই। যখন আমরা অনেকগুলি প্রোগ্রাম লাইব্রেরিতে জেনেরিক ইন্টারফেস ডিজাইন করি, তখন আমাদের ইন্টারফেসটির বিভিন্ন ধরণের বাস্তবায়ন হওয়া আরও বেশি গুরুত্বপূর্ণ implement এটি মোনাড ধারণার সাধারণতা যা আমরা এত বেশি মূল্যবান, কারণ শ্রেণি তত্ত্বটি এত বিমূর্ত যে এর ধারণাগুলি প্রোগ্রামিংয়ের জন্য এত কার্যকর।
তবে এটি খুব কমই আশ্চর্যজনক যে, আমরা নীচে উপস্থাপিত মনাদগুলির সাধারণীকরণের বিভাগীয় তত্ত্বের সাথে নিবিড় সংযোগ রয়েছে। তবে আমরা জোর দিয়ে বলছি যে আমাদের উদ্দেশ্যটি অত্যন্ত ব্যবহারিক: এটি 'বিভাগের তত্ত্বটি বাস্তবায়ন' নয়, এটি সংযুক্তি গ্রন্থাগারগুলির কাঠামোগত গঠনের আরও সাধারণ উপায় খুঁজে বের করা। এটি কেবল আমাদের সৌভাগ্য যে গণিতবিদরা ইতিমধ্যে আমাদের জন্য অনেক কাজ করেছেন!
থেকে তীর থেকে Generalising Monads জন হিউজেস দ্বারা
বিশ্বের যা প্রয়োজন তা অন্য একটি মোনাদ ব্লগ পোস্ট, তবে আমি মনে করি এটি বন্য অঞ্চলে বিদ্যমান মনাদগুলি সনাক্ত করতে কার্যকর।
উপরেরটি সিয়েরপিনস্কি ত্রিভুজ নামে একটি ফ্র্যাক্টাল, এটি আঁকতে কেবল একমাত্র ফ্র্যাক্টাল মনে আছে। ফ্র্যাক্টালগুলি উপরের ত্রিভুজগুলির মতো স্ব-অনুরূপ কাঠামো, যাতে অংশগুলি সম্পূর্ণরূপে সমান হয় (এক্ষেত্রে প্যারেন্ট ত্রিভুজ হিসাবে ঠিক অর্ধেক স্কেল)।
মনাদাগুলি ভঙ্গুর। একটি monadic ডেটা কাঠামো দেওয়া, এর মান তথ্য কাঠামোর অন্য মান গঠন করতে রচনা করা যেতে পারে। এ কারণেই এটি প্রোগ্রামিংয়ে উপকারী এবং এটি বিভিন্ন পরিস্থিতিতে ঘটে।
এই প্রশ্নটি ঠিকঠাক করার জন্য http://code.google.com/p/monad-tutorial/ একটি কাজ চলছে।
নীচে {| a |m}
monadic ডেটা কিছু অংশ উপস্থাপন করুন। একটি ডেটা টাইপ যা বিজ্ঞাপন দেয় a
:
(I got an a!)
/
{| a |m}
ফাংশন,, f
একটি মোনাড তৈরি করতে জানে, যদি কেবল এটির একটি থাকে a
:
(Hi f! What should I be?)
/
(You?. Oh, you'll be /
that data there.) /
/ / (I got a b.)
| -------------- |
| / |
f a |
|--later-> {| b |m}
এখানে আমরা ফাংশনটি দেখি, f
একটি মনডকে মূল্যায়নের চেষ্টা করি তবে তিরস্কার হয়।
(Hmm, how do I get that a?)
o (Get lost buddy.
o Wrong type.)
o /
f {| a |m}
ফাংশন,, f
এটি a
ব্যবহার করে উত্তোলনের একটি উপায় খুঁজে বের করে >>=
।
(Muaahaha. How you
like me now!?)
(Better.) \
| (Give me that a.)
(Fine, well ok.) |
\ |
{| a |m} >>= f
সামান্য f
জানেন না, মোনাদ এবং যৌথভাবে >>=
আছেন।
(Yah got an a for me?)
(Yeah, but hey |
listen. I got |
something to |
tell you first |
...) \ /
| /
{| a |m} >>= f
তবে তারা আসলে কী সম্পর্কে কথা বলবে? ঠিক আছে, এটি মোনাডের উপর নির্ভর করে। বিমূর্তে একমাত্র কথা বলার সীমিত ব্যবহার রয়েছে; আপনার বোঝার বাইরে যাওয়ার জন্য নির্দিষ্ট মনডের সাথে কিছু অভিজ্ঞতা থাকতে হবে।
উদাহরণস্বরূপ, ডেটা টাইপ হতে পারে
data Maybe a = Nothing | Just a
একটি monad উদাহরণ রয়েছে যা নিম্নলিখিতগুলির মতো কাজ করবে ...
যেখানে, যদি মামলা হয় Just a
(Yah what is it?)
(... hm? Oh, |
forget about it. |
Hey a, yr up.) |
\ |
(Evaluation \ |
time already? \ |
Hows my hair?) | |
| / |
| (It's |
| fine.) /
| / /
{| a |m} >>= f
তবে এর ক্ষেত্রে Nothing
(Yah what is it?)
(... There |
is no a. ) |
| (No a?)
(No a.) |
| (Ok, I'll deal
| with this.)
\ |
\ (Hey f, get lost.)
\ | ( Where's my a?
\ | I evaluate a)
\ (Not any more |
\ you don't. |
| We're returning
| Nothing.) /
| | /
| | /
| | /
{| a |m} >>= f (I got a b.)
| (This is \
| such a \
| sham.) o o \
| o|
|--later-> {| b |m}
সুতরাং সম্ভবত মোনাদ একটি গণনা চালিয়ে যেতে দেয় যদি এটিতে আসলে a
বিজ্ঞাপনটি থাকে তবে এটি যদি না করে তবে এই গণনাটি বাতিল করে দেয়। ফলাফল, তবে এখনও monadic তথ্য এক টুকরা, যদিও আউটপুট না f
। এই কারণে, মোনড ব্যর্থতার প্রসঙ্গে প্রতিনিধিত্ব করতে ব্যবহৃত হয়।
বিভিন্ন মনাদ বিভিন্ন আচরণ করে। তালিকা হ'ল monadic দৃষ্টান্ত সহ অন্যান্য ধরণের ডেটা। তারা নিম্নলিখিতগুলির মতো আচরণ করে:
(Ok, here's your a. Well, its
a bunch of them, actually.)
|
| (Thanks, no problem. Ok
| f, here you go, an a.)
| |
| | (Thank's. See
| | you later.)
| (Whoa. Hold up f, |
| I got another |
| a for you.) |
| | (What? No, sorry.
| | Can't do it. I
| | have my hands full
| | with all these "b"
| | I just made.)
| (I'll hold those, |
| you take this, and /
| come back for more /
| when you're done /
| and we'll do it /
| again.) /
\ | ( Uhhh. All right.)
\ | /
\ \ /
{| a |m} >>= f
এই ক্ষেত্রে, ফাংশনটি কীভাবে এটির ইনপুট থেকে একটি তালিকা তৈরি করতে জানত, তবে অতিরিক্ত ইনপুট এবং অতিরিক্ত তালিকাগুলি দিয়ে কী করবে তা জানত না। বাঁধাই >>=
, f
একাধিক আউটপুট একত্রিত করে সাহায্য করেছে। আমি এই উদাহরণটি অন্তর্ভুক্ত করে এটি দেখানোর জন্য যে >>=
নিষ্কাশনের জন্য দায়বদ্ধ থাকাকালীন a
এটির শেষ অবধি আউটপুট অ্যাক্সেসও রয়েছে f
। প্রকৃতপক্ষে, এটি কখনই নিষ্কাশন করবে না a
যতক্ষণ না এটি জেনে থাকে চূড়ান্ত আউটপুটে একই ধরণের প্রসঙ্গ রয়েছে।
অন্যান্য মনদেও রয়েছে যা বিভিন্ন প্রসঙ্গে উপস্থাপন করতে ব্যবহৃত হয়। এখানে আরও কয়েকটি বৈশিষ্ট্য রয়েছে। IO
একসংখ্যা আসলে একটি নেই a
, কিন্তু এটি একটি লোক জানে এবং যে পাবেন a
আপনার জন্য। State st
একসংখ্যা একটি গোপন লুকোবার জায়গা রয়েছে st
যে এটি পাস হবে f
টেবিলের নিচে, যদিও f
শুধু একটি চাওয়ার এসে a
। Reader r
একসংখ্যা অনুরূপ State st
যদিও এটি শুধুমাত্র দেয়, f
এ বর্ণন r
।
এই সমস্ত ক্ষেত্রে মূল বিষয়টি হ'ল যে কোনও ধরণের ডেটা যা নিজেকে মোনাড হিসাবে ঘোষণা করা হয় তা মোনাড থেকে মান বের করার জন্য কিছু প্রকারের প্রসঙ্গ ঘোষণা করে। এ সব থেকে বড় লাভ? ঠিক আছে, এটি কোনও প্রসঙ্গে প্রসঙ্গের সাথে গণনা সোপান করার পক্ষে যথেষ্ট সহজ। একাধিক প্রসঙ্গের বোঝা হিসাব একসাথে স্ট্রিং করার সময় এটি অগোছালো হতে পারে। মোনাড অপারেশনগুলি প্রসঙ্গের ইন্টারঅ্যাকশনগুলি সমাধান করার যত্ন নেয় যাতে প্রোগ্রামারকে এটির প্রয়োজন হয় না।
দ্রষ্টব্য, >>=
স্বায়ত্তশাসন থেকে দূরে কিছু নিয়ে এই ব্যবহারের ফলে বিশৃঙ্খলা সহজ হয় f
। Nothing
উদাহরণস্বরূপ, উপরের ক্ষেত্রে এটির ক্ষেত্রে f
আর কী করা উচিত তা আর সিদ্ধান্ত নিতে পারে না Nothing
; এটি এনকোড করা আছে >>=
। এটি বাণিজ্য বন্ধ। ক্ষেত্রে যদি f
করণীয় সিদ্ধান্ত নেওয়ার প্রয়োজন হয় Nothing
তবে f
থেকে শুরু করে কোনও কাজ করা উচিত Maybe a
ছিল Maybe b
। এই ক্ষেত্রে, Maybe
একটি একসংখ্যা হচ্ছে অপ্রাসঙ্গিক।
নোট করুন, তবে, কখনও কখনও কোনও ডেটা টাইপ তার কনস্ট্রাক্টরগুলি রফতানি করে না (আপনাকে IO দেখছে), এবং আমরা যদি বিজ্ঞাপনিত মানের সাথে কাজ করতে চাই তবে আমাদের মনডিক ইন্টারফেসের সাথে কাজ করা ছাড়া খুব কম উপায় আছে।
একটি মোনাড হল এমন একটি জিনিস যা পরিবর্তিত অবস্থায় থাকা অবজেক্টগুলিকে আবদ্ধ করতে ব্যবহৃত হয়। এটি প্রায়শই ভাষাগুলিতে মুখোমুখি হয় যা অন্যথায় আপনাকে সংশোধনযোগ্য রাষ্ট্র (যেমন, হাস্কেল) রাখার অনুমতি দেয় না।
উদাহরণ I / O ফাইলের জন্য হবে।
আপনি মোনাড ব্যবহার করা কোডে পরিবর্তিত রাষ্ট্রের প্রকৃতিকে আলাদা করতে আই / ও ফাইলের জন্য একটি মোনাড ব্যবহার করতে সক্ষম হবেন। মোনাডের অভ্যন্তরীণ কোডটি মোনাডের বাইরের বিশ্বের পরিবর্তিত রাষ্ট্রকে কার্যকরভাবে উপেক্ষা করতে পারে - এটি আপনার প্রোগ্রামের সামগ্রিক প্রভাব সম্পর্কে যুক্তিযুক্ত হওয়া অনেক সহজ করে তোলে।