একটি data
ঘোষণায়, একটি টাইপ কনস্ট্রাক্টর সমান চিহ্নের বাম পাশে জিনিস। তথ্য কন্সট্রাকটর (গুলি) ডান দিকে জিনিস সমান চিহ্ন আছে। আপনি টাইপ কনস্ট্রাক্টর ব্যবহার করেন যেখানে কোনও টাইপ প্রত্যাশিত হয় এবং আপনি ডেটা কনস্ট্রাক্টর ব্যবহার করেন যেখানে কোনও মান প্রত্যাশিত।
ডেটা কনস্ট্রাক্টর
জিনিসগুলিকে সহজ করার জন্য, আমরা একটি রঙের প্রতিনিধিত্ব করে এমন একটি উদাহরণ দিয়ে শুরু করতে পারি।
data Colour = Red | Green | Blue
এখানে আমাদের তিনটি ডেটা কনস্ট্রাক্টর রয়েছে। Colour
এটি একটি প্রকার, এবং Green
এমন একটি নির্মাতা যা টাইপের মান ধারণ করে Colour
। একইভাবে, Red
এবং Blue
উভয় কনস্ট্রাক্টর যা টাইপের মানগুলি তৈরি করে Colour
। আমরা কল্পনা করতে পারি যদিও এটি স্পাইসিং করা যায়!
data Colour = RGB Int Int Int
আমাদের এখনও ঠিক টাইপ রয়েছে Colour
, তবে RGB
এটি কোনও মূল্য নয় - এটি একটি ফাংশন যা তিনটি ইনস নেয় এবং একটি মান ফেরত দেয় ! RGB
টাইপ আছে
RGB :: Int -> Int -> Int -> Colour
RGB
এটি একটি ডেটা কনস্ট্রাক্টর যা একটি ফাংশন যা তার মানগুলি আর্গুমেন্ট হিসাবে গ্রহণ করে এবং তারপরে নতুন মান তৈরি করতে সেগুলি ব্যবহার করে। আপনি যদি কোনও অবজেক্ট ভিত্তিক প্রোগ্রামিং করেন তবে আপনার এটি স্বীকৃতি দেওয়া উচিত। ওওপি-তে, কনস্ট্রাক্টররা আর্গুমেন্ট হিসাবে কিছু মানও নেয় এবং একটি নতুন মান ফেরত দেয়!
এই ক্ষেত্রে, আমরা RGB
তিনটি মান প্রয়োগ করি, আমরা একটি রঙ মান পেতে!
Prelude> RGB 12 92 27
#0c5c1b
আমরা ডেটা কনস্ট্রাক্টর প্রয়োগ করে প্রকারের মান তৈরি করেছি Colour
। একটি ডেটা কনস্ট্রাক্টর একটি হয় ভেরিয়েবলের মতো মান ধারণ করে, বা অন্যান্য মানকে এর যুক্তি হিসাবে গ্রহণ করে এবং একটি নতুন মান তৈরি করে । আপনি যদি পূর্ববর্তী প্রোগ্রামিং করে থাকেন তবে এই ধারণাটি আপনার কাছে খুব অদ্ভুত হওয়া উচিত নয়।
বিচ্ছেদ
আপনি যদি স্টোরের জন্য বাইনারি ট্রি তৈরি করতে চান তবে আপনি এমন String
কিছু করার কথা ভাবতে পারেন
data SBTree = Leaf String
| Branch String SBTree SBTree
আমরা এখানে যা দেখি তা হ'ল একটি প্রকার SBTree
যা দুটি ডেটা কনস্ট্রাক্টর ধারণ করে। অন্য কথায়, দুটি ফাংশন (যথা Leaf
এবং Branch
) যা SBTree
ধরণের মান তৈরি করবে । বাইনারি গাছগুলি কীভাবে কাজ করে সে সম্পর্কে আপনি যদি অবগত না হন তবে কেবল সেখানেই স্তব্ধ হন। বাইনারি গাছগুলি কীভাবে কাজ করে তা আপনাকে আসলে জানতে হবে না, কেবল এটি যে String
কোনওভাবে সঞ্চয় করে ।
আমরা আরও দেখতে পেলাম যে উভয় ডেটা কনস্ট্রাক্টর একটি String
যুক্তি নিয়েছে - এটি সেই স্ট্রিং যা তারা গাছের মধ্যে সংরক্ষণ করতে চলেছে।
কিন্ত! আমরা যদি সংরক্ষণ করতে সক্ষম হতে চাই তবে কী হবে Bool
, আমাদের একটি নতুন বাইনারি ট্রি তৈরি করতে হবে। এটি এর মতো দেখতে পারে:
data BBTree = Leaf Bool
| Branch Bool BBTree BBTree
কনস্ট্রাক্টর টাইপ করুন
উভয় SBTree
এবং BBTree
টাইপ নির্মাণকারী। তবে একটি উদ্ভট সমস্যা আছে। আপনি দেখতে পান যে তারা কতটা একই রকম? এটি এমন একটি চিহ্ন যা আপনি সত্যিই কোথাও একটি প্যারামিটার চান।
সুতরাং আমরা এটি করতে পারি:
data BTree a = Leaf a
| Branch a (BTree a) (BTree a)
এখন আমরা টাইপ কনস্ট্রাক্টরের কাছে প্যারামিটার হিসাবে একটি টাইপ ভেরিয়েবল প্রবর্তন করি a
। এই ঘোষণাপত্রে, BTree
একটি ফাংশনে পরিণত হয়েছে। এটি তার আর্গুমেন্ট হিসাবে একটি প্রকার নেয় এবং এটি একটি নতুন ধরণের দেয় ।
এখানে গুরুত্বপূর্ণ পার্থক্য বিবেচনা হয় কংক্রিট টাইপ (উদাহরণ অন্তর্ভুক্ত Int
, [Char]
এবং Maybe Bool
) যা একটি টাইপ যে আপনার প্রোগ্রামে একটি মান নির্ধারিত করা যেতে পারে, এবং একটি টাইপ কন্সট্রাকটর ফাংশন যা আপনাকে একটি টাইপ ভোজন প্রয়োজন হতে পাবে একটি মান নির্ধারিত। একটি মান লিখুন "তালিকা" কখনো হতে পারে না কারণ এটি একটি "তালিকা করা প্রয়োজন কিছু "। একই আত্মায়, কোনও মান কখনই "বাইনারি ট্রি" আকারের হতে পারে না কারণ এটি "বাইনারি ট্রি কিছু সংরক্ষণের " হওয়া দরকার।
যদি আমরা ভিতরে প্রবেশ করি তবে বলুন, Bool
যুক্তি হিসাবে BTree
এটি প্রকারটি প্রদান করে BTree Bool
যা একটি বাইনারি গাছ যা সংরক্ষণ করে Bool
। প্রকারের a
সাথে চলকটির প্রতিটি ঘটনাকে প্রকারের সাথে প্রতিস্থাপন করুন Bool
এবং আপনি কীভাবে এটি সত্য তা দেখতে পারেন।
আপনি যদি চান, আপনি BTree
এই ধরনের সঙ্গে একটি ফাংশন হিসাবে দেখতে পারেন
BTree :: * -> *
ধরণগুলি কিছুটা প্রকারের মতো হয় - এটি *
একটি কংক্রিটের ধরণের ইঙ্গিত দেয়, তাই আমরা বলি BTree
একটি কংক্রিটের থেকে কংক্রিটের ধরণে।
মোড়ক উম্মচন
এক মুহুর্তে এখানে ফিরে যান এবং সাদৃশ্যগুলি নোট করুন।
প্যারামিটারগুলির সাথে ডেটা কনস্ট্রাক্টররা যদি আমাদের মানগুলিতে সামান্য প্রকরণ চান তবে আমরা শীতল - আমরা সেই পরিবর্তনগুলি পরামিতিগুলিতে রাখি এবং যে লোকটি মান তৈরি করে তাদের সিদ্ধান্ত নিতে দেয় যে তারা কী যুক্তি যুক্ত করবে। একই অর্থে, পরামিতিগুলির সাথে টাইপ কনস্ট্রাক্টরগুলি দুর্দান্ত আমরা যদি আমাদের ধরণের কিছুটা ভিন্নতা চাই! আমরা এই বিভিন্নতাগুলিকে পরামিতি হিসাবে রেখেছি এবং যে লোকটি প্রকারটি তৈরি করে তাদের সিদ্ধান্ত নিতে দেয় যে তারা কী যুক্তি যুক্ত করবে।
একটি কেস স্টাডি
এখানে বাড়ির প্রসারিত হিসাবে, আমরা Maybe a
প্রকারটি বিবেচনা করতে পারি । এর সংজ্ঞাটি হ'ল
data Maybe a = Nothing
| Just a
এখানে, Maybe
একটি প্রকারের কনস্ট্রাক্টর যা একটি কংক্রিটের ধরণ দেয়। Just
একটি ডেটা কনস্ট্রাক্টর যা একটি মান দেয়। Nothing
একটি ডেটা কনস্ট্রাক্টর যাতে একটি মান রয়েছে। আমরা এর ধরণের দিকে নজর দিলে Just
আমরা তা দেখতে পাই
Just :: a -> Maybe a
অন্য কথায়, Just
টাইপের মান নেয় a
এবং প্রকারের মান দেয় Maybe a
। আমরা যদি ধরণের দিকে তাকাই তবে Maybe
আমরা তা দেখতে পাই
Maybe :: * -> *
অন্য কথায়, Maybe
একটি কংক্রিট টাইপ নেয় এবং একটি কংক্রিট টাইপ প্রদান করে।
আরেকবার! একটি কংক্রিট টাইপ এবং একটি টাইপ কনস্ট্রাক্টর ফাংশনের মধ্যে পার্থক্য। আপনি যদি একটি Maybe
এক্সিকিউট করার চেষ্টা করেন তবে আপনি এর একটি তালিকা তৈরি করতে পারবেন না
[] :: [Maybe]
আপনি একটি ত্রুটি পাবেন। তবে আপনি Maybe Int
বা এর একটি তালিকা তৈরি করতে পারেন Maybe a
। কারণ Maybe
এটি একটি প্রকারের কনস্ট্রাক্টর ফাংশন, তবে একটি তালিকার জন্য একটি কংক্রিটের ধরণের মান থাকতে হবে। Maybe Int
এবং Maybe a
কংক্রিটের ধরণের (বা যদি আপনি চান, কনস্ট্রাক্টর ফাংশনগুলি টাইপ করার জন্য কলগুলি যা কংক্রিটের ধরণগুলি ফেরত দেয়))
Car
উভয়ই টাইপ কনস্ট্রাক্টর (বাম দিকে=
) এবং ডেটা কনস্ট্রাক্টর (ডানদিকে)। প্রথম উদাহরণে,Car
টাইপ কনস্ট্রাক্টর কোনও আর্গুমেন্ট নেয় না, দ্বিতীয় উদাহরণে এটি তিনটি লাগে। উভয় উদাহরণে,Car
ডেটা কনস্ট্রাক্টর তিনটি আর্গুমেন্ট গ্রহণ করে (তবে those যুক্তিগুলির ধরণগুলি একটি ক্ষেত্রে স্থির এবং অন্য প্যারামিটারাইজডে থাকে)।