আসুন প্রথমে বিমূর্ত ধারণাটি শেখার এবং সেগুলির নির্দিষ্ট উদাহরণ শেখার মধ্যে পার্থক্য করি।
আপনি সমস্ত নির্দিষ্ট উদাহরণকে খুব বেশি উপেক্ষা করতে যাচ্ছেন না, সাধারণ কারণে যে তারা সম্পূর্ণরূপে সর্বব্যাপী। প্রকৃতপক্ষে, বিমূর্ততাগুলি বেশিরভাগ অংশে বিদ্যমান কারণ তারা নির্দিষ্ট উদাহরণগুলির সাহায্যে যেভাবেই করা হবে সেগুলি একত্রিত করে।
অন্যদিকে বিমূর্ততাগুলি অবশ্যই কার্যকরভাবে কার্যকর তবে এগুলি তাত্ক্ষণিকভাবে প্রয়োজনীয় নয়। আপনি পুরোপুরি পুরোপুরি বিমূর্তি উপেক্ষা করে এবং সরাসরি বিভিন্ন ধরণের সরাসরি ব্যবহার করতে পারেন। আপনি এগুলি অবশেষে বুঝতে চাইবেন, তবে আপনি পরে সর্বদা এটিতে ফিরে আসতে পারেন। প্রকৃতপক্ষে, আমি প্রায় গ্যারান্টি দিতে পারি যে আপনি যদি এটি করেন তবে আপনি যখন তা ফিরে পেয়েছেন তখন আপনি আপনার কপালটি চাপড়বেন এবং ভাববেন যে আপনি কেন সুবিধাজনক সাধারণ উদ্দেশ্যমূলক সরঞ্জামগুলি ব্যবহার না করে কঠোর উপায়ে সমস্ত সময় ব্যয় করেছিলেন।
Maybe a
উদাহরণ হিসাবে নিন । এটি কেবল একটি ডেটা টাইপ:
data Maybe a = Just a | Nothing
এটি স্ব স্ব নথিপত্র ছাড়াও সব; এটি একটি alচ্ছিক মান। হয় আপনার কাছে "জাস্ট" কিছু টাইপ রয়েছে a
, বা আপনার কাছে কিছুই নেই। বলুন আপনার কাছে কোনও ধরণের লুকের ফাংশন রয়েছে, যা উপস্থিত নাও হতে পারে এমন Maybe String
একটি String
মান সন্ধান করার জন্য প্রত্যাবর্তন করে । সুতরাং আপনি মানটির সাথে মিল রেখে এটি দেখতে কোনটি:
case lookupFunc key of
Just val -> ...
Nothing -> ...
এখানেই শেষ!
সত্যিই, আপনার প্রয়োজন মতো আর কিছুই নেই। কোন Functor
এস বা Monad
এস বা অন্য কিছু। এগুলি Maybe a
মানগুলি ব্যবহার করার সাধারণ উপায়গুলি প্রকাশ করে ... তবে এগুলি কেবল "মূর্তিগুলি", "নকশার ধরণগুলি", আপনি যা কিছু বলতে চান তা।
আপনি যে জায়গাটি একেবারে এড়াতে পারবেন না তা সেই জায়গাটির সাথেই রয়েছে IO
তবে এটি যেভাবেই রহস্যজনক ব্ল্যাক বক্স, তাই এটি কী Monad
বা যা কিছু তা বোঝার চেষ্টা করার মতো নয় ।
আসলে, এখানে সব আপনার জন্য একটি ঠকাই শীট এর সত্যিই সম্পর্কে জানা প্রয়োজন IO
এখন জন্য:
যদি কোনও কিছুর একটি প্রকার থাকে IO a
তবে এর অর্থ এটি এমন একটি প্রক্রিয়া যা কিছু করে এবং একটি a
মান ফেলে its
do
স্বরলিপিটি ব্যবহার করে আপনার যখন কোনও ব্লকের কোড রয়েছে , তখন এই জাতীয় কিছু লেখা:
do -- ...
inp <- getLine
-- etc...
... মানে ডানদিকের পদ্ধতিটি কার্যকর করা<-
এবং ফলাফলটি বামদিকে নামের সাথে অর্পণ করা।
তবে আপনার যদি এরকম কিছু থাকে:
do -- ...
let x = [foo, bar]
-- etc...
... এর অর্থ =
বাম দিকের নামের সাথে ডানদিকে ডানদিকে সরল অভিব্যক্তির (কোনও প্রক্রিয়া নয়) মূল্য নির্ধারণ করা ।
আপনি যদি কোনও মান নির্দিষ্ট করে না দিয়ে কিছু রাখেন তবে:
do putStrLn "blah blah, fishcakes"
... এর অর্থ একটি প্রক্রিয়া চালানো এবং যে কোনও কিছু ফিরে আসে তা উপেক্ষা করা। কিছু প্রক্রিয়া প্রকার থাকা IO ()
--দী ()
ধরনের একটি স্থানধারক যে কিছু বলে না সাজানোর, তাই যে শুধু পদ্ধতি মানে কিছু করে এবং একটি মান ফেরত দেয় না। void
অন্যান্য ভাষায় কোনও ফাংশনের মতো বাছাই করুন ।
একই পদ্ধতি একাধিকবার কার্যকর করা বিভিন্ন ফলাফল দিতে পারে; এ ধরণের ধারণা। এ কারণেই কোনও IO
মানটি থেকে "অপসারণ" করার কোনও উপায় নেই কারণ কোনও জিনিসের IO
কোনও মূল্য নয়, এটি একটি মান পাওয়ার পদ্ধতি।
একটি do
ব্লকের শেষ লাইনটি অবশ্যই কোনও নির্ধারিত প্লেইন পদ্ধতি হতে হবে, যেখানে সেই পদ্ধতির রিটার্ন মান পুরো ব্লকের জন্য ফেরতের মান হয়ে যায়। আপনি যদি রিটার্নের মানটি ইতিমধ্যে নির্ধারিত কিছু মান ব্যবহার করতে চান তবে return
ফাংশনটি একটি সরল মান নেয় এবং আপনাকে কোনও অপ-পদ্ধতি দেয় যা সেই মানটি ফেরত দেয়।
তা বাদে বিশেষ কিছু নেই IO
; এই পদ্ধতিগুলি প্রকৃতপক্ষে নিজেরাই সরল মূল্য and এবং আপনি এগুলি চারপাশে পাস এবং বিভিন্ন উপায়ে তাদের একত্রিত করতে পারেন। এটি কেবল তখনই যখন তারা যে কোনও কিছু do
করে বলা হয় main
এমন কোনও ব্লকে মৃত্যুদন্ড কার্যকর করা হয় ।
সুতরাং, একেবারে বোরিং, স্টেরিওটাইপিকাল উদাহরণ প্রোগ্রামের মতো কিছুতে:
hello = do putStrLn "What's your name?"
name <- getLine
let msg = "Hi, " ++ name ++ "!"
putStrLn msg
return name
... আপনি এটি একটি আবশ্যক প্রোগ্রামের মতোই পড়তে পারেন। আমরা নামের একটি প্রক্রিয়া সংজ্ঞায়িত করছি hello
। মৃত্যুদন্ড কার্যকর করা হলে, প্রথমে এটি আপনার নাম জিজ্ঞাসা করে একটি বার্তা মুদ্রণের জন্য একটি প্রক্রিয়া চালায়; এরপরে এটি এমন একটি প্রক্রিয়া চালায় যা ইনপুটটির একটি লাইন পড়ে এবং ফলাফল নির্ধারিত করে name
; তারপরে এটি নামের সাথে একটি অভিব্যক্তি নির্ধারণ করে msg
; তারপরে এটি বার্তাটি প্রিন্ট করে; তারপরে এটি পুরো ব্লকের ফলাফল হিসাবে ব্যবহারকারীর নাম দেয় returns যেহেতু name
একটি String
, এর অর্থ এই যে hello
প্রক্রিয়াটি একটি ফেরত দেয় String
, তাই এর টাইপ থাকে IO String
। এবং এখন আপনি এই প্রক্রিয়াটি অন্যরকমভাবে চালিত করতে পারেন ঠিক যেমন এটি কার্যকর করে getLine
।
পিএফএফ, মনডস। কার দরকার?