নমুনা ছাড়াও, হাস্কেলের মধ্যে @ এর অর্থ কী?


15

আমি বর্তমানে হাস্কেল অধ্যয়ন করছি এবং এমন একটি প্রকল্প বোঝার চেষ্টা করব যা হাস্কেলকে ক্রিপ্টোগ্রাফিক অ্যালগরিদমগুলি প্রয়োগ করতে ব্যবহার করে। গ্রেট গুড অনলাইনের জন্য আপনি শিখুন একটি হাস্কেল পড়ার পরে , আমি সেই প্রকল্পের কোডটি বুঝতে শুরু করি। তারপরে আমি দেখতে পেলাম যে আমি "@" চিহ্ন সহ নিম্নলিখিত কোডটিতে আটকে রয়েছি:

-- | Generate an @n@-dimensional secret key over @rq@.
genKey :: forall rq rnd n . (MonadRandom rnd, Random rq, Reflects n Int)
       => rnd (PRFKey n rq)
genKey = fmap Key $ randomMtx 1 $ value @n

এখানে এলোমেলো এমটিএক্স নির্ধারণ করা হয়েছে:

-- | A random matrix having a given number of rows and columns.
randomMtx :: (MonadRandom rnd, Random a) => Int -> Int -> rnd (Matrix a)
randomMtx r c = M.fromList r c <$> replicateM (r*c) getRandom

এবং PRFKey নীচে সংজ্ঞায়িত করা হয়েছে:

-- | A PRF secret key of dimension @n@ over ring @a@.
newtype PRFKey n a = Key { key :: Matrix a }

সমস্ত তথ্যের উত্স যা আমি জানতে পারি যে @ হ'ল সেই বিন্যাস, তবে কোডের এই অংশটি দৃশ্যত এমনটি নয়। আমি অনলাইন টিউটোরিয়াল, ব্লগ এবং এমনকি হাস্কেল ২০১০ ভাষা প্রতিবেদনটি https://www.haskell.org/definition/haskell2010.pdf এ দেখেছি । এই প্রশ্নের কোনও উত্তর নেই।

এই পদ্ধতিতে @ ব্যবহার করে আরও কোড স্নিপেটগুলি এই প্রকল্পে পাওয়া যাবে:

-- | Generate public parameters (\( \mathbf{A}_0 \) and \(
-- \mathbf{A}_1 \)) for @n@-dimensional secret keys over a ring @rq@
-- for gadget indicated by @gad@.
genParams :: forall gad rq rnd n .
            (MonadRandom rnd, Random rq, Reflects n Int, Gadget gad rq)
          => rnd (PRFParams n gad rq)
genParams = let len = length $ gadget @gad @rq
                n   = value @n
            in Params <$> (randomMtx n (n*len)) <*> (randomMtx n (n*len))

আমি এই বিষয়ে কোন সাহায্যের গভীরভাবে প্রশংসা করি।


11
এগুলি টাইপ অ্যাপ্লিকেশনএই প্রশ্নোত্তরও দেখুন । আপনি সেই প্রতিশ্রুতিটিও দেখতে পারেন যা কোডগুলিতে তাদের প্রবর্তন করেছিল।
মিকাএলএফ

লিঙ্কগুলির জন্য অনেক ধন্যবাদ! এগুলি হ'ল আমি যা খুঁজছি। আশ্চর্যজনকভাবে, আপনি এমনকি কোডটির প্রতিশ্রুতি সনাক্ত করতে পারেন! তার জন্য অনেক ধন্যবাদ। আপনি কীভাবে এটি আবিষ্কার করবেন তা সম্পর্কে কেবল কৌতূহল? @ মিকায়েলএফ
সিগুরডাব্লু

2
গিথুবের গিট দোষের নিজস্ব ইন্টারফেস রয়েছে , যা আপনাকে বলবে যে প্রতিটা লাইন সর্বশেষ পরিবর্তন করা হয়েছিল।
মিকাএলএফ

এই দরকারী টিপ জন্য অনেক ধন্যবাদ :)
SigurdW

1
@ মিশেললিচার্ড খুব খুশি যে আপনি এটি থেকে উপকৃত হতে পারেন। আমি সাহায্য করার জন্য সময় ব্যয় করা সদয় লোকের প্রতি কৃতজ্ঞ। আশা করি উত্তরটি অন্যকেও সহায়তা করতে পারে।
সিগুরডাব্লু

উত্তর:


16

এটি @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থাকলেও কল করতে দেয় । ভাল না. পরিবর্তে,n5

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))

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

সমাপ্তি: এগুলি খুব উন্নত এক্সটেনশন। আপনি যদি শিক্ষানবিশ হন তবে আপনাকে এই কৌশলগুলির দিকে ধীরে ধীরে অগ্রগতি করতে হবে। যদি আপনি কেবল একটি সংক্ষিপ্ত অধ্যয়নের পরে এগুলি ধরে না করতে পারেন তবে হতাশ হবেন না, এতে কিছুটা সময় লাগবে। একবারে একটি ছোট পদক্ষেপ করুন, প্রতিটি বৈশিষ্ট্যটির বিন্দুটি বোঝার জন্য কিছু অনুশীলন সমাধান করুন। আপনি আটকে থাকবেন এবং আপনার কাছে সর্বদা স্ট্যাক ওভারফ্লো থাকবে :-)


আপনার বিস্তারিত ব্যাখ্যার জন্য আপনাকে অনেক ধন্যবাদ! এটি সত্যিই আমার সমস্যা সমাধান করে এবং আমার ধারণা আমি উত্তরটি খুঁজে পেতে আমার আরও অনেক সময় প্রয়োজন। আপনার পরামর্শের জন্য আপনাকে ধন্যবাদ!
সিগুরডাব্লু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.