এখানে, "মান", "প্রকার", এবং "প্রকার" এর আনুষ্ঠানিক অর্থ রয়েছে, সুতরাং তাদের সাধারণ ইংরেজি ব্যবহার বা অটোমোবাইলকে শ্রেণিবদ্ধকরণের উপমা বিবেচনা করে কেবল আপনাকে এ পর্যন্ত পাওয়া যাবে।
আমার উত্তরটি বিশেষত হাস্কেলের প্রসঙ্গে এই শর্তগুলির আনুষ্ঠানিক অর্থের সাথে সম্পর্কিত; এই অর্থগুলি গাণিতিক / সিএস "টাইপ থিওরি" তে ব্যবহৃত অর্থগুলির (যদিও এর সাথে সত্যই অভিন্ন নয়) উপর ভিত্তি করে। সুতরাং, এটি খুব ভাল "কম্পিউটার বিজ্ঞান" উত্তর হবে না, তবে এটি হাস্কেলের একটি উত্তম উত্তর হিসাবে পরিবেশন করা উচিত।
হাস্কেল (এবং অন্যান্য ভাষাগুলিতে), এটি এমন কোনও প্রোগ্রামের এক্সপ্রেশনটিতে একটি টাইপ নির্ধারণে সহায়ক হতে সাহায্য করে যা এক্সপ্রেশনটির অনুমোদিত মানগুলির শ্রেণীর বর্ণনা দেয়। আমি এখানে অনুমান আপনি যথেষ্ট উদাহরণ দেখা করেছি বুঝতে কেন এটা জানাতে চাই যে এক্সপ্রেশনে দরকারী হবে sqrt (a**2 + b**2)
, ভেরিয়েবল a
এবং b
সবসময় ধরনের মান হতে হবে Double
এবং বলে, String
এবং Bool
যথাক্রমে। মূলত, প্রকারভেদগুলি আমাদের বহিঃপ্রকাশ / প্রোগ্রাম লিখতে সহায়তা করে যা বিভিন্ন ধরণের মানকে সঠিকভাবে কাজ করবে ।
এখন, এমন কিছু যা আপনি বুঝতে পারেননি তা হ্যাস্কেল প্রকার, স্বাক্ষর টাইপের মতো:
fmap :: Functor f => (a -> b) -> f a -> f b
এগুলি আসলে একটি টাইপ-লেভেল হাস্কেল সাবল্যাংগয়েজে লেখা। প্রোগ্রামের পাঠ্যটি Functor f => (a -> b) -> f a -> f b
হ'ল - বেশ আক্ষরিক - এই সাবল্যাংগুয়েজে একটি টাইপ প্রকাশ । Sublanguage অপারেটার অন্তর্ভুক্ত (যেমন, ->
এই ভাষাতে অধিকার মিশুক পোতা অপারেটর), ভেরিয়েবল (যেমন, f
, a
, এবং b
), এবং অন্য এক ধরনের মত প্রকাশের "APPLICATION" (যেমন, f a
হয় f
প্রয়োগ a
)।
আমি কী উল্লেখ করেছি যে কীভাবে বহু ভাষায় প্রোগ্রাম এক্সপ্রেশনগুলিতে এক্সপ্রেশন মানের মূল্য শ্রেণীর বর্ণনা দেওয়ার জন্য টাইপগুলি অর্পণ করা সহায়ক? ওয়েল, এই টাইপ-স্তরের sublanguage এ, এক্সপ্রেশন নির্ণয় ধরনের (বদলে মান ) এবং দায়িত্ব অর্পণ করা সহায়ক হচ্ছে শেষ পর্যন্ত ধরণের ক্লাস বর্ণনা করতে এক্সপ্রেশন টাইপ করতে ধরনের তারা প্রতিনিধিত্ব করার জন্য অনুমোদিত। মূলত, থাকার ধরণের টাইপ এক্সপ্রেশন যে সঠিকভাবে বিস্তৃত উপর কাজ করবে লিখিতভাবে আমাদের সহায়তা ধরনের ।
সুতরাং, মান হয় ধরনের যেমন ধরনের হয় ধরণের , এবং ধরনের আমাদের লিখুন সাহায্য মান পর্যায়ের প্রোগ্রাম যখন ধরণের আমাদের লিখুন সাহায্য টাইপ পর্যায়ের প্রোগ্রাম।
এই ধরণের দেখতে কেমন? ভাল, স্বাক্ষর টাইপ বিবেচনা করুন:
id :: a -> a
টাইপ অভিব্যক্তি যদি a -> a
বৈধ বলে, কি ধরনের এর ধরনের আমরা পরিবর্তনশীল অনুমতি উচিত a
হবে? ঠিক আছে, টাইপ এক্সপ্রেশন:
Int -> Int
Bool -> Bool
বৈধ দেখতে, তাই প্রকারগুলি Int
এবং Bool
স্পষ্টতই সঠিক ধরণের । তবে আরও জটিল ধরণের যেমন:
[Double] -> [Double]
Maybe [(Double,Int)] -> Maybe [(Double,Int)]
বৈধ চেহারা। প্রকৃতপক্ষে, যেহেতু আমাদের id
ক্রিয়াকলাপগুলি করতে সক্ষম হওয়া উচিত , এমনকি:
(a -> a) -> (a -> a)
দেখতে ভাল. সুতরাং, Int
, Bool
, [Double]
, Maybe [(Double,Int)]
, এবং a -> a
মত সব বর্ণন ধরনের অধিকার ধরনের ।
অন্য কথায়, দেখে মনে হচ্ছে এটি কেবল এক ধরণের আছে , আসুন একে *
ইউনিক্স ওয়াইল্ডকার্ডের মতো বলি এবং প্রতিটি ধরণের গল্পের সমাপ্তি একই রকম *
।
রাইট?
ভাল, বেশ না। এটি প্রমাণিত হয় যে Maybe
, এটি নিজেই, কোনও প্রকারের মত প্রকাশের মতোই বৈধ Maybe Int
(অনেকগুলি একইভাবে sqrt
, নিজে থেকে, যেমন একটি মূল্য প্রকাশের মত বৈধ sqrt 25
)। তবে , নিম্নলিখিত ধরণের অভিব্যক্তিটি বৈধ নয়:
Maybe -> Maybe
কারণ, যখন Maybe
একটি টাইপ অভিব্যক্তি, এটা প্রতিনিধিত্ব করে না ধরনের এর টাইপ মান করতে পারেন। সুতরাং, যে আমরা কিভাবে সংজ্ঞায়িত করা উচিত *
- এটা ধরনের এর ধরনের আছে মান; এটা পছন্দ "সম্পূর্ণ" ধরনের রয়েছে Double
বা Maybe [(Double,Int)]
কিন্তু বাদ অসম্পূর্ণ, মূল্যহীন ধরনের পছন্দ Either String
। সরলতার জন্য, আমি এই ধরণের সম্পূর্ণ ধরণের *
"কংক্রিট প্রকারগুলি" বলব , যদিও এই পরিভাষা সর্বজনীন নয়, এবং "কংক্রিটের ধরণ" বলতে একটি সি ++ প্রোগ্রামার বলতে খুব আলাদা কিছু বোঝায়।
এখন, টাইপ এক্সপ্রেশনে a -> a
, যতদিন প্রকার a
হয়েছে ধরনের *
(কংক্রিট ধরনের ধরনের), টাইপ মত প্রকাশের ফলাফলের a -> a
হবে এছাড়াও আছে ধরনের *
(অর্থাত, কংক্রিট ধরনের ধরনের)।
সুতরাং, এ ধরনের এর টাইপ হয় Maybe
? ভাল, Maybe
অন্য একটি কংক্রিট ধরণের উত্পাদন করতে একটি কংক্রিট টাইপ প্রয়োগ করা যেতে পারে। সুতরাং,Maybe
একটি টাইপ-স্তরের ফাংশন যে একটি লাগে মত একটু মত দেখাচ্ছে টাইপ এর ধরনের *
এবং একটি ফেরৎ টাইপ এর ধরনের *
। আমরা যদি একটি মান স্তর ফাংশন যে একটি গ্রহণ ছিল মান এর টাইপ Int
এবং ফিরে মান এর টাইপ Int
আমরা এটিকে দিতে চাই টাইপ স্বাক্ষর Int -> Int
, তাই উপমা দ্বারা আমরা দিতে হবে Maybe
একটি ধরনের স্বাক্ষর * -> *
। জিএইচসিআই সম্মত:
> :kind Maybe
Maybe :: * -> *
এখানে ফিরে যাচ্ছি:
fmap :: Functor f => (a -> b) -> f a -> f b
এই ধরণের স্বাক্ষরে, ভেরিয়েবলের f
दयालु * -> *
এবং ভেরিয়েবল থাকে a
এবং b
প্রকার থাকে *
; অন্তর্নির্মিত অপারেটরের ->
দয়া আছে * -> * -> *
(এটি *
বাম দিকে এবং ডানদিকে একটি ধরণের ধরণের লাগে এবং এক ধরণের ধরণের ফেরত দেয় *
)। এগুলি এবং ধরণের অনুমানের নিয়মগুলি থেকে, আপনি অনুমান করতে পারেন যে a -> b
প্রকারের সাথে একটি বৈধ প্রকার *
, f a
এবং f b
প্রকারের সাথে বৈধ প্রকার *
এবং (a -> b) -> f a -> f b
বৈধ প্রকারের *
।
অন্য কথায়, সংকলকটি (a -> b) -> f a -> f b
সঠিক প্রকারের ভেরিয়েবলের জন্য বৈধভাবে ভেরিয়েবলের জন্য বৈধ যাচাই করার জন্য টাইপ এক্সপ্রেশনটি "টাইপ চেক" sqrt (a**2 + b**2)
করতে পারে এটি সঠিক ধরণের ভেরিয়েবলের জন্য বৈধ যাচাই করার জন্য "পরীক্ষা করে" টাইপ করে।
"প্রকার" বনাম "প্রকারের" জন্য পৃথক পদ ব্যবহার করার কারণ (যেমন, "ধরণের ধরণের" সম্পর্কে কথা না বলা) বেশিরভাগ ক্ষেত্রে কেবল বিভ্রান্তি এড়ানোর জন্য। ধরণের খুব থেকে ভিন্ন রুপ দেওয়ার উপরে ধরনের অন্তত প্রথমে, এবং পুরোপুরি ভিন্ন আচরণ করে বলে মনে হচ্ছে। (উদাহরণস্বরূপ, প্রতিটি "স্বাভাবিক" টাইপের একই ধরণের থাকে *
এবং ধরণের a -> b
হয় *
না এমন ধারণাটি ঘিরে আপনার মাথাটি গুটিয়ে নিতে কিছুটা সময় লাগে * -> *
))
এর কয়েকটি historicalতিহাসিকও। জিএইচসি হাস্কেল যেমন বিকশিত হয়েছে, মান, প্রকার এবং প্রকারের মধ্যে পার্থক্য ঝাপসা হতে শুরু করেছে। এই দিনগুলিতে মানগুলি প্রকারে "প্রচারিত" হতে পারে এবং প্রকার এবং প্রকারগুলি সত্যই একই জিনিস। সুতরাং, আধুনিক হাস্কেলতে, উভয়ই মানগুলির প্রকার এবং এআরই প্রকারগুলি (প্রায়) রয়েছে এবং প্রকারের ধরণগুলি কেবল আরও প্রকারের।
@ ব্যবহারকারী21820 "প্রকার এবং প্রকারগুলি আসলে একই জিনিস" এর কিছু অতিরিক্ত ব্যাখ্যা চেয়েছিল। একটু পরিষ্কার হওয়ার জন্য, আধুনিক জিএইচসি হাস্কেল-তে (সংস্করণ 8.0.1, আমি মনে করি), বিভিন্ন ধরণের সংকলক কোডে প্রকার এবং প্রকারগুলি একত্রে আচরণ করা হয়। সংকলকটি যথাক্রমে কোনও মানের ধরণ বা প্রকারের প্রকারের বিষয়ে অভিযোগ করছে কিনা তার উপর নির্ভর করে "প্রকার" এবং "প্রকার" এর মধ্যে পার্থক্য করার জন্য ত্রুটি বার্তাগুলিতে কিছু চেষ্টা করে।
এছাড়াও, যদি কোনও এক্সটেনশান সক্ষম না করা হয় তবে তারা পৃষ্ঠের ভাষায় সহজেই পার্থক্য করতে পারে। উদাহরণস্বরূপ, সিন্টেক্সে প্রকারের (মানগুলির) একটি প্রতিনিধিত্ব রয়েছে (উদাহরণস্বরূপ, স্বাক্ষর প্রকারে) তবে ধরণের (প্রকারের) হ'ল - আমি মনে করি - সম্পূর্ণ অন্তর্নিহিত, এবং যেখানে স্পষ্ট থাকে তার কোনও স্পষ্ট বাক্য গঠন নেই।
তবে, আপনি যদি উপযুক্ত এক্সটেনশানগুলি চালু করেন তবে প্রকার এবং প্রকারের মধ্যে পার্থক্য মূলত অদৃশ্য হয়ে যায়। উদাহরণ স্বরূপ:
{-# LANGUAGE GADTs, TypeInType #-}
data Foo where
Bar :: Bool -> * -> Foo
এখানে, Bar
(একটি মান এবং উভয়) এক প্রকার। একটি প্রকার হিসাবে, এটির ধরণটি Bool -> * -> Foo
, যা একটি ধরণের স্তরের ফাংশন যা এক ধরণের Bool
(যা একটি ধরণের, তবে এক ধরণের) এবং এক ধরণের ধরণের লাগে এবং এক প্রকারের *
উত্পাদন করে Foo
। তাই:
type MyBar = Bar True Int
সঠিকভাবে দয়া করে-চেক।
@ আন্ড্রেজবাউর তার উত্তরে যেমন ব্যাখ্যা করেছেন, প্রকার এবং প্রকারের মধ্যে পার্থক্য করার এই ব্যর্থতাটি অনিরাপদ - একটি ধরণের / ধরণের *
যার নিজস্ব / প্রকারটি নিজেই (আধুনিক হাস্কেলের ক্ষেত্রে এটি) প্যারাডক্সের দিকে পরিচালিত করে। যাইহোক, হাস্কেলের টাইপ সিস্টেম ইতিমধ্যে সমাপ্ত না হওয়ায় প্যারাডক্সে পূর্ণ। তাই এটি কোনও বড় বিষয় হিসাবে বিবেচিত হয় না।