এটি @n
আধুনিক হাস্কেলের একটি উন্নত বৈশিষ্ট্য, যা সাধারণত LYAH এর মতো টিউটোরিয়াল দ্বারা আবৃত হয় না বা রিপোর্টটি পাওয়া যায় না।
একে টাইপ অ্যাপ্লিকেশন বলা হয় এবং এটি একটি জিএইচসি ভাষার এক্সটেনশন। এটি বোঝার জন্য, এই সাধারণ পলিমারফিক ফাংশনটি বিবেচনা করুন
dup :: forall a . a -> (a, a)
dup x = (x, x)
স্বজ্ঞাত কলিং dup
নিম্নলিখিত হিসাবে কাজ করে:
- আহ্বানকারী একটি বেছে টাইপ
a
- আহ্বানকারী একটি বেছে মান
x
পূর্বে মনোনীত ধরনেরa
dup
তারপরে একটি মানের সাথে উত্তর দিন (a,a)
এক অর্থে, dup
দুটি আর্গুমেন্ট লাগে: প্রকার a
এবং মান x :: a
। যাইহোক, GHC সাধারণত টাইপ অনুমান করতে সক্ষম হয় a
(যেমন থেকে x
, অথবা প্রসঙ্গ যেখানে আমরা ব্যবহার করছেন থেকে dup
), তাই আমরা সাধারণত শুধুমাত্র এক যুক্তি পাস dup
, যথা x
। উদাহরণস্বরূপ, আমরা আছে
dup True :: (Bool, Bool)
dup "hello" :: (String, String)
...
এখন, যদি আমরা a
স্পষ্টভাবে পাস করতে চান ? ঠিক আছে, সেক্ষেত্রে আমরা TypeApplications
এক্সটেনশনটি চালু করতে এবং লিখতে পারি
dup @Bool True :: (Bool, Bool)
dup @String "hello" :: (String, String)
...
@...
প্রকার বহনকারী আর্গুমেন্টগুলি (মানগুলি নয়) নোট করুন । এগুলি এমন কিছু যা সংকলনের সময় বিদ্যমান, কেবলমাত্র - রানটাইমে যুক্তির উপস্থিতি নেই।
আমরা এটা কেন চাই? ঠিক আছে, কখনও কখনও x
কাছাকাছি হয় না , এবং আমরা সঠিকটি চয়ন করতে সংকলকটি আরও বাড়িয়ে দিতে চাই a
। যেমন
dup @Bool :: Bool -> (Bool, Bool)
dup @String :: String -> (String, String)
...
টাইপ অ্যাপ্লিকেশনগুলি প্রায়শই কিছু অন্যান্য এক্সটেনশনের সংমিশ্রণে কার্যকর হয় যা দ্বিপাক্ষিক প্রকার বা টাইপ পরিবারের মতো জিএইচসি-র জন্য টাইপ অনুক্রমকে অসহনীয় করে তোলে। আমি সেগুলি নিয়ে আলোচনা করব না, তবে আপনি কেবল বুঝতে পারবেন যে কখনও কখনও আপনাকে সত্যিকারের শক্তিশালী টাইপ-স্তরের বৈশিষ্ট্যগুলি ব্যবহার করার সময় সংকলকটিকে সহায়তা করা প্রয়োজন।
এখন, আপনার নির্দিষ্ট কেস সম্পর্কে। আমার কাছে সমস্ত বিবরণ নেই, আমি গ্রন্থাগারটি জানি না, তবে এটি সম্ভবত আপনার ধরণের স্তরেরn
এক ধরণের প্রাকৃতিক-সংখ্যার মান উপস্থাপন করে । এখানে আমরা উল্লিখিত প্লাসগুলি DataKinds
, সম্ভবত GADTs
এবং কিছু টাইপক্লাস যন্ত্রপাতি মতো উন্নত এক্সটেনশনে ডাইভিং করছি । যদিও আমি সমস্ত কিছু ব্যাখ্যা করতে পারি না, আশা করি আমি কিছু প্রাথমিক অন্তর্দৃষ্টি সরবরাহ করতে পারি। intuitively,
foo :: forall n . some type using n
আর্গুমেন্ট হিসাবে গ্রহণ করে @n
, এক ধরণের সংকলন-সময় প্রাকৃতিক, যা রানটাইমে পাস হয় না। পরিবর্তে,
foo :: forall n . C n => some type using n
@n
(সংকলন-সময়) একসাথে এমন প্রমাণের সাথে নেয় যা n
সীমাবদ্ধতা পূরণ করে C n
। পরবর্তীটি একটি রান-টাইম আর্গুমেন্ট, যা এর আসল মানটি প্রকাশ করতে পারে n
। প্রকৃতপক্ষে, আপনার ক্ষেত্রে, আমি অনুমান করি যে আপনার কাছে অস্পষ্টভাবে কিছু মিল রয়েছে
value :: forall n . Reflects n Int => Int
যা কোডটি মূলত টাইপ-লেভেলকে শব্দ-স্তরে আনতে দেয়, মূলত "টাইপ" কে "মান" হিসাবে অ্যাক্সেস করে। (উপরের প্রকারটিকে "দ্ব্যর্থক" হিসাবে বিবেচনা করা হয়, যাইহোক - আপনাকে সত্যই @n
নিস্তার করতে হবে))
শেষ অবধি: কেন n
আমরা যদি পরে শব্দটিকে পদ স্তরে রূপান্তর করি তবে টাইপ স্তরে কেন পাস করতে হবে ? এর মতো ফাংশনগুলি সহজভাবে লিখতে সহজ হবে না
foo :: Int -> ...
foo n ... = ... use n
পরিবর্তে আরও জটিল
foo :: forall n . Reflects n Int => ...
foo ... = ... use (value @n)
সৎ উত্তরটি হ'ল: হ্যাঁ, এটি আরও সহজ হবে। তবে, n
ধরণের স্তরে থাকা সংকলকটিকে আরও স্থিতিক চেক সম্পাদন করতে দেয়। উদাহরণস্বরূপ, আপনি "পূর্ণসংখ্যার মডুলো n
" উপস্থাপনের জন্য একটি টাইপ চান এবং সেগুলি যুক্ত করার অনুমতি দিতে পারেন। জমিদারি
data Mod = Mod Int -- Int modulo some n
foo :: Int -> Mod -> Mod -> Mod
foo n (Mod x) (Mod y) = Mod ((x+y) `mod` n)
কাজ করে, তবে এটির কোনও চেক নেই x
এবং y
এটি একই মডুলাসের। আমরা সাবধান না হলে আমরা আপেল এবং কমলা যুক্ত করতে পারি। আমরা পরিবর্তে লিখতে পারে
data Mod n = Mod Int -- Int modulo n
foo :: Int -> Mod n -> Mod n -> Mod n
foo n (Mod x) (Mod y) = Mod ((x+y) `mod` n)
যা আরও ভাল, তবে এখনও না foo 5 x y
থাকলেও কল করতে দেয় । ভাল না. পরিবর্তে,n
5
data Mod n = Mod Int -- Int modulo n
-- a lot of type machinery omitted here
foo :: forall n . SomeConstraint n => Mod n -> Mod n -> Mod n
foo (Mod x) (Mod y) = Mod ((x+y) `mod` (value @n))
জিনিস ভুল হতে বাধা দেয়। সংকলক স্থিতিশীলভাবে সমস্ত কিছু পরীক্ষা করে। কোডটি ব্যবহার করা শক্ত, হ্যাঁ, তবে এক অর্থে এটি ব্যবহার করা আরও শক্ত করা পুরো বিষয়টি: আমরা ব্যবহারকারীকে ভুল মডুলাসের কিছু যুক্ত করার চেষ্টা করা অসম্ভব করে তুলতে চাই।
সমাপ্তি: এগুলি খুব উন্নত এক্সটেনশন। আপনি যদি শিক্ষানবিশ হন তবে আপনাকে এই কৌশলগুলির দিকে ধীরে ধীরে অগ্রগতি করতে হবে। যদি আপনি কেবল একটি সংক্ষিপ্ত অধ্যয়নের পরে এগুলি ধরে না করতে পারেন তবে হতাশ হবেন না, এতে কিছুটা সময় লাগবে। একবারে একটি ছোট পদক্ষেপ করুন, প্রতিটি বৈশিষ্ট্যটির বিন্দুটি বোঝার জন্য কিছু অনুশীলন সমাধান করুন। আপনি আটকে থাকবেন এবং আপনার কাছে সর্বদা স্ট্যাক ওভারফ্লো থাকবে :-)