একটি monad দেখতে বিভিন্ন উপায়


29

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

দেখুন 1: একটি লেবেল হিসাবে Monad

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

myfunction :: IO Int

মাইফাঙ্কশন এমন একটি ফাংশন যা যখনই সম্পাদিত হয় এটি একটি মান মান অর্জন করবে। ফলাফলের ধরণটি ইনট নয়, আইও ইনট হয়। সুতরাং, আইও হ'ল ইন্টার মানটির একটি লেবেল যা ব্যবহারকারীকে জানাতে সতর্ক করে যে আইটি অ্যাকশনটি করা হয়েছে এমন কোনও প্রক্রিয়ার ফলাফল হিসাবে মানটি মান হয়।

ফলস্বরূপ, এই আন্ত মানটি মান হিসাবে চিহ্নিত হয়েছে যা আইও সহ একটি প্রক্রিয়া থেকে এসেছে সুতরাং এই মানটি "নোংরা"। আপনার প্রক্রিয়া আর শুদ্ধ নয়।

দেখুন 2: মোনাদকে একটি ব্যক্তিগত স্থান হিসাবে যেখানে দুষ্টু জিনিসগুলি ঘটতে পারে।

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

দেখুন 3: বিভাগ তত্ত্ব হিসাবে Monad

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

এই মতামত কি সঠিক? কোনটি আরও সঠিক?


5
# 2 সাধারণভাবে যা হয় তা নয়। আসলে, এটি আইও-তে সীমাবদ্ধ, এবং দরকারী দৃষ্টিকোণ নয় (সিএফ। কী একটি মোনাড নয় )। এছাড়াও, "কঠোর" সাধারণত কোনও সম্পত্তির নাম হিসাবে নেওয়া হয় যা হাস্কেলের হাতে নেই (যথা কঠোর মূল্যায়ন)। যাইহোক, মোনাডস তা পরিবর্তন করে না (আবার দেখুন, কী একটি মোনাড নয়)

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

ভাষার অংশ হিসাবে কমন লিস্পের নিজস্ব সংকলক রয়েছে। হাস্কেলের মনাদস রয়েছে।
নেস

উত্তর:


33

# 1 এবং # 2 দর্শনগুলি সাধারণভাবে ভুল।

  1. যে কোনও ডেটা ধরণের ধরণের * -> *লেবেল হিসাবে কাজ করতে পারে, ম্যানডস এর চেয়ে অনেক বেশি।
  2. ( IOমোনাড বাদে ) একটি মোনাডের মধ্যে গণনা অপরিষ্কার নয়। এগুলি কেবল এমন গণনা উপস্থাপন করে যা আমরা পার্শ্ব প্রতিক্রিয়া হিসাবে দেখছি, তবে সেগুলি খাঁটি।

এই দুটি ভুল বোঝাবুঝি IOমনাদকে কেন্দ্র করেই এসেছে যা আসলে কিছুটা বিশেষ।

সম্ভব হলে বিভাগের তত্ত্বে না গিয়ে আমি # 3 কে আরও বিস্তৃত করার চেষ্টা করব।


স্ট্যান্ডার্ড গণনা

একটি কার্মিক প্রোগ্রামিং ভাষা সকল কম্পিউটেশন একটি উৎস ধরণ এবং একটি টার্গেট ধরনের সঙ্গে ফাংশন হিসেবে দেখা যেতে পারে: f :: a -> b। যদি কোনও ফাংশনে একাধিক আর্গুমেন্ট থাকে তবে আমরা কারি করে এটি এক-যুক্তি ফাংশনে রূপান্তর করতে পারি ( হাস্কেল উইকিও দেখুন )। এবং যদি আমরা শুধু একটি মূল্য আছে (0 আর্গুমেন্ট সহ একটি ফাংশন), আমরা এটি একটি ফাংশন যে একটি আর্গুমেন্ট নেয় মধ্যে রূপান্তর করতে পারেন ইউনিট টাইপ : ।x :: a(\_ -> x) :: () -> a

.অপারেটর ব্যবহার করে এই জাতীয় ফাংশন রচনা করে আমরা আরও জটিল প্রোগ্রামগুলি আরও সহজতর আকারে তৈরি করতে পারি । উদাহরণস্বরূপ, যদি আমাদের থাকে f :: a -> bএবং g :: b -> cআমরা পাই g . f :: a -> c। নোট করুন যে এটি আমাদের রূপান্তরিত মানগুলির জন্যও কাজ করে: আমাদের যদি x :: aএটি থাকে এবং এটি আমাদের প্রতিনিধিত্বতে রূপান্তরিত করে, আমরা পাই f . ((\_ -> x) :: () -> a) :: () -> b

এই উপস্থাপনার কিছু খুব গুরুত্বপূর্ণ বৈশিষ্ট্য রয়েছে, যথা:

  • আমাদের একটি খুব বিশেষ ফাংশন রয়েছে - প্রতিটি ধরণের জন্য পরিচয় ফাংশন । এটি সম্মানের সাথে একটি পরিচয় উপাদান : উভয় এবং সমান ।id :: a -> aa.ff . idid . f
  • ফাংশন রচনা অপারেটর .হয় মিশুক

মোনাডিক গণনা

মনে করুন আমরা কয়েকটি বিশেষ বিভাগের গণনা বাছাই করে কাজ করতে চাই, যার ফলাফলটিতে একক রিটার্ন মান ছাড়া আরও কিছু রয়েছে। আমরা "আরও কিছু" এর অর্থ কী তা নির্দিষ্ট করে বলতে চাই না, আমরা জিনিসগুলি যতটা সম্ভব সাধারণ রাখতে চাই। "আরও কিছু" উপস্থাপনের সর্বাধিক সাধারণ উপায় এটিকে প্রকারের ফাংশন হিসাবে উপস্থাপন করে - mএক ধরণের * -> *(যেমন এটি এক প্রকারকে অন্য রূপান্তর করে)। সুতরাং আমরা প্রতিটি বিভাগে যে কাজ করতে চাই তার জন্য আমাদের কিছু ধরণের ফাংশন থাকবে m :: * -> *। (ইন Haskell,, mহয় [], IO, Maybe, ইত্যাদি) এবং বিভাগ ইচ্ছার ধরনের সব ফাংশন রয়েছে a -> m b

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

  • একটি অপারেটর আছে করার জন্য (এটা কল দিন <=<যে ফাংশন composes) f :: a -> m bএবং g :: b -> m cকিছু মধ্যে g <=< f :: a -> m c। এবং, এটি অবশ্যই সাহসী হতে হবে।
  • প্রতিটি ধরণের জন্য কিছু পরিচয় ফাংশন রাখতে, আসুন এটি কল করুন return। আমরা চাই যে f <=< returnহিসাবে একই fএবং একই return <=< f

কোন m :: * -> *, যার জন্য আমরা এই ধরনের ফাংশন returnএবং <=<একটি বলা হয় একসংখ্যা । এটি আমাদেরকে সাধারণ বিষয়গুলির মতোই সাধারণ গণনাগুলি তৈরি করতে দেয়, তবে এখন রিটার্ন মানগুলির প্রকারগুলি সুবিন্যস্ত হয় m

(আসলে, আমি একটু শব্দ নির্যাতিত বিভাগ এখানে। ক্যাটেগরী তত্ত্ব অর্থে আমরা আমাদের নির্মাণ একটি বিভাগ আমরা জানি পরই এই আইন আনুগত্য কল করতে পারেন।)

হাসকেলে মনড

হাস্কেল (এবং অন্যান্য কার্যকরী ভাষা) তে আমরা বেশিরভাগ মান নিয়ে কাজ করি না, ধরণের ফাংশন দিয়ে () -> a। সুতরাং <=<প্রতিটি monad জন্য সংজ্ঞা পরিবর্তে , আমরা একটি ফাংশন সংজ্ঞায়িত (>>=) :: m a -> (a -> m b) -> m b। এই জাতীয় বিকল্প সংজ্ঞা সমতুল্য, আমরা >>=ব্যবহার করে <=<এবং বিপরীতভাবে প্রকাশ করতে পারি (অনুশীলন হিসাবে চেষ্টা করুন, বা উত্সগুলি দেখুন )। নীতিটি এখন কম স্পষ্ট, তবে এটি একই রকম রয়েছে: আমাদের ফলাফল সর্বদা প্রকারের m aএবং আমরা প্রকারের ক্রিয়াগুলি রচনা করি a -> m b

আমরা তৈরি প্রতিটি মোনাডের জন্য, আমাদের অবশ্যই এটি পরীক্ষা করতে returnএবং <=<আমাদের প্রয়োজনীয় বৈশিষ্ট্যগুলি ভুলে যাওয়া উচিত নয় : সাহচর্যতা এবং বাম / ডান পরিচয়। ব্যবহার করে প্রকাশ করা হয়েছে returnএবং এগুলিকে মনোড আইন>>= বলা হয়

একটি উদাহরণ - তালিকা

যদি আমরা mহতে বেছে নিই তবে আমরা []এক ধরণের ক্রিয়াকলাপ পাই a -> [b]। এই জাতীয় ফাংশনগুলি অ-বিড়ম্বনামূলক গণনার প্রতিনিধিত্ব করে, যার ফলাফল এক বা একাধিক মান হতে পারে তবে মানও নেই। এটি তথাকথিত তালিকা মোনাডকে জন্ম দেয় । এর রচনা f :: a -> [b]এবং g :: b -> [c]নিম্নলিখিতটির মতো কাজ করে: এর g <=< f :: a -> [c]অর্থ হ'ল সম্ভাব্য সকল প্রকারের ফলাফল গণনা করা [b], gতাদের প্রত্যেকের জন্য প্রয়োগ করা এবং সমস্ত ফলাফল একক তালিকায় সংগ্রহ করা। হাস্কেলে প্রকাশ করেছেন

return :: a -> [a]
return x = [x]
(<=<) :: (b -> [c]) -> (a -> [b]) -> (a -> [c])
g (<=<) f  = concat . map g . f

বা ব্যবহার >>=

(>>=) :: [a] -> (a -> [b]) -> [b]
x >>= f  = concat (map f x)

মনে রাখবেন যে এই উদাহরণে রিটার্নের ধরনগুলি [a]তাই এটি সম্ভব ছিল যে তাদের মধ্যে কোনও ধরণের কোনও মূল্য নেই a। প্রকৃতপক্ষে, কোনও মোনাডের জন্য এমন কোনও প্রয়োজন নেই যে রিটার্ন টাইপের এমন মান থাকতে হবে। কিছু মনদে সর্বদা থাকে (পছন্দ IOবা State), কিন্তু কিছু না, পছন্দ []বা না Maybe

আইও মনাদ

আমি যেমন উল্লেখ করেছি, IOমোনাড কিছুটা বিশেষ। প্রকারের মান বলতে প্রোগ্রামের পরিবেশের সাথে আলাপচারিত করে নির্মিত ধরণের মানIO a বোঝায় সুতরাং (অন্যান্য সমস্ত মনডের মত নয়) আমরা কিছু খাঁটি নির্মাণ ব্যবহার করে ধরণের মান বর্ণনা করতে পারি না । এখানে কেবল একটি ট্যাগ বা একটি লেবেল যা পরিবেশের সাথে যোগাযোগ করে এমন গণনাগুলি পৃথক করে। এটি (একমাত্র ক্ষেত্রে) যেখানে # 1 এবং # 2 মতামতগুলি সঠিক।aIO aIO

জন্য IOএকসংখ্যা:

  • এর গঠন f :: a -> IO bএবং g :: b -> IO cঅর্থ: fপরিবেশের সাথে ইন্টারেক্ট করে এমন গণনা এবং তারপরেg পরিবেশের সাথে ইন্টারঅ্যাক্ট করে ফলাফলকে গণনা করে এমন মান গণনা করে comp
  • returnকেবলমাত্র মানটিতে IO"ট্যাগ" যুক্ত করে (আমরা পরিবেশকে অক্ষুণ্ন রেখে ফলাফলটি কেবল "গণনা" করতে পারি)।
  • সংকলক দ্বারা মোনাড আইন (সাহসীতা, পরিচয়) গ্যারান্টিযুক্ত।

কিছু নোট:

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

3
দুর্দান্ত উত্তর। আমি স্পষ্ট করব যে IOভাষার দৃষ্টিকোণ থেকে বিশেষ শব্দার্থবিজ্ঞান নেই। এটি বিশেষ নয় , এটি অন্য কোনও কোডের মতো আচরণ করে। কেবল রানটাইম লাইব্রেরি বাস্তবায়ন বিশেষ। এছাড়াও, ( unsafePerformIO) পালানোর জন্য একটি বিশেষ উদ্দেশ্যমূলক উপায় রয়েছে । আমি মনে করি এটি গুরুত্বপূর্ণ কারণ লোকেরা প্রায়শই IOএকটি বিশেষ ভাষার উপাদান বা একটি ঘোষণামূলক ট্যাগ হিসাবে ভাবেন । এইটা না.
usr ডিরেক্টরির

2
@ ইউএসআর ভাল পয়েন্ট। আমি যুক্ত করব যে অনিরাপদ পারফর্মফর্মআইওটি সত্যই অনিরাপদ এবং এটি কেবল বিশেষজ্ঞদের দ্বারা ব্যবহার করা উচিত। এটি আপনাকে সমস্ত কিছু ভাঙ্গতে দেয়, উদাহরণস্বরূপ, আপনি একটি ফাংশন তৈরি করতে পারেন coerce :: a -> bযা কোনও দুটি ধরণের রূপান্তর করে (এবং বেশিরভাগ ক্ষেত্রে আপনার প্রোগ্রামটি ক্র্যাশ করে)। এই উদাহরণটি দেখুন - আপনি এমনকি কোনও ফাংশনকে Intইত্যাদিতে রূপান্তর করতে পারেন
পেটর পুডলিক

আর একটি "বিশেষ যাদু" মোনাড হবে এসটি, যা আপনাকে মেমরির রেফারেন্সগুলি ঘোষণা করতে দেয় যা আপনি পড়তে এবং যেমনটি ফিট দেখতে পান ঠিক তেমন লিখতে পারেন (তবে কেবল মোনাডের মধ্যেই), এবং তারপরে আপনি ফলাফলটি বের করতে পারবেনrunST :: (forall s. GHC.ST.ST s a) -> a
সারা

5

দেখুন 1: একটি লেবেল হিসাবে Monad

"ফলস্বরূপ, এই আন্ত মানটি মান হিসাবে চিহ্নিত হয়েছে যা আইও সহ একটি প্রক্রিয়া থেকে এসেছে সুতরাং এই মানটি" ​​নোংরা ""

"আইও ইনট" সাধারণভাবে কোনও মান মান হয় না (যদিও এটি "রিটার্ন 3" এর মতো কিছু ক্ষেত্রেও হতে পারে)। এটি এমন একটি প্রক্রিয়া যা কিছু অন্তর্গত মানকে আউটপুট করে। এই "পদ্ধতির" বিভিন্ন মৃত্যুদণ্ড কার্যকর হতে পারে বিভিন্ন মান মান।

একটি মোনাড মি, একটি এম্বেড (অপরিহার্য) "প্রোগ্রামিং ল্যাঙ্গুয়েজ": এই ভাষার ভিতরে কিছু "পদ্ধতি" সংজ্ঞায়িত করা সম্ভব। একটি monadic মান (টাইপ মা এর), এই "প্রোগ্রামিং ল্যাঙ্গুয়েজে" একটি পদ্ধতি যা টাইপ এ এর ​​মানকে আউটপুট করে।

উদাহরণ স্বরূপ:

foo :: IO Int

এমন কিছু প্রক্রিয়া যা আন্তঃ টাইপের মানকে আউটপুট করে।

তারপর:

bar :: IO (Int, Int)
bar = do
  a <- foo
  b <- foo
  return (a,b)

এমন কিছু প্রক্রিয়া যা দুটি (সম্ভবত পৃথক) ইনট আউটপুট দেয়।

এই জাতীয় "ভাষা" কিছু অপারেশন সমর্থন করে:

  • দুটি পদ্ধতি (মা এবং এমবি) হতে পারে "কনটেনটেটেড": আপনি প্রথমটি তৈরির পরে বৃহত্তর পদ্ধতি (মা >> এমবি) তৈরি করতে পারেন দ্বিতীয়টি;

  • প্রথমটির আউটপুট (ক) এর চেয়ে বেশি কী দ্বিতীয়টিকে প্রভাবিত করতে পারে (মা >> = \ এ -> ...);

  • একটি পদ্ধতি (রিটার্ন এক্স) কিছু ধ্রুবক মান (x) পেতে পারে।

বিভিন্ন এম্বেড থাকা প্রোগ্রামিং ল্যাঙ্গুয়েজগুলি তাদের সমর্থন করে এমন ধরণের জিনিসগুলিতে পৃথক হয়:

  • এলোমেলো মান প্রদান;
  • "কাঁটাচামচ" (দ্য [মোনাড);
  • ব্যতিক্রম (নিক্ষেপ / ধরা) (দ্য ইয়ার ই মোনাদ);
  • সুস্পষ্ট ধারাবাহিকতা / কলসিসি সমর্থন;
  • অন্যান্য "এজেন্টদের" বার্তা প্রেরণ / গ্রহণ;
  • ভেরিয়েবলগুলি তৈরি করুন, সেট করুন এবং পড়ুন (এই প্রোগ্রামিং ভাষার স্থানীয়) (এসটি মোনাদ)।

1

মোনাডিক ক্লাসের সাথে কোনও মোনাডিক টাইপকে বিভ্রান্ত করবেন না।

একটি monadic টাইপ (অর্থাত্ monad শ্রেণীর উদাহরণ হিসাবে একটি প্রকার) একটি নির্দিষ্ট সমস্যা সমাধান করবে (নীতিগতভাবে, প্রতিটি monadic টাইপ পৃথক এক সমাধান করে): রাজ্য, র্যান্ডম, হতে পারে, আইও। এগুলির সমস্ত প্রসঙ্গে প্রবন্ধের (আপনি যাকে "লেবেল" বলে থাকেন, তবে এটি তাদের মনাদ হিসাবে তৈরি করে না)।

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

দেখুন মোনাড শ্রেণি কী সমাধান করে?

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