হাস্কেল / জিএইচসি-র ora forall` কীওয়ার্ডটি কী করে?


312

আমি forallকীওয়ার্ডটি কীভাবে তথাকথিত "অস্তিত্বের ধরণের "গুলিতে ব্যবহৃত হয় তা বুঝতে শুরু করি :

data ShowBox = forall s. Show s => SB s

এটি কেবল কীভাবে forallব্যবহৃত হয় সে সম্পর্কে এটি কেবলমাত্র একটি উপসেট and

runST :: forall a. (forall s. ST s a) -> a

বা কেন এগুলি আলাদা তা ব্যাখ্যা করে:

foo :: (forall a. a -> a) -> (Char, Bool)
bar :: forall a. ((a -> a) -> (Char, Bool))

বা পুরো RankNTypesজিনিস ...

আমি একাডেমিক পরিবেশে সাধারণত যে ধরণের ভাষা স্বাভাবিক তা স্পষ্ট, বর্ণহীন ইংরেজী পছন্দ করি। এটির উপর আমি যে ব্যাখ্যাটি পড়তে চাইছি তার বেশিরভাগ ক্ষেত্রেই (সার্চ ইঞ্জিনগুলির মাধ্যমে আমি যেগুলি খুঁজে পেতে পারি) এই সমস্যাগুলি রয়েছে:

  1. তারা অসম্পূর্ণ। তারা এই শব্দ ( "অস্তিত্ববাদের ধরনের" মত) ব্যবহার একটি অংশ যার ফলে পর্যন্ত আমি কোডটি পড়া আমাকে খুশি মনে ব্যাখ্যা করেন যে একটি সম্পূর্ণ ভিন্ন ভাবে এটি ব্যবহার করে (যেমন runST, fooএবং barউপরে)।
  2. তারা এই অনুমানের সাথে ঘন হয়ে আছে যে আমি পৃথক পৃথক গণিত, বিভাগের তত্ত্ব বা বিমূর্ত বীজগণিতের যে কোনও শাখায় এই সপ্তাহে জনপ্রিয়। (আমি শব্দ পড় নি যদি "কাগজ সঙ্গে পরামর্শ যাই হোক না কেন আবার, এটা খুব শীঘ্রই হবে বাস্তবায়নে বিস্তারিত জানার জন্য"।)
  3. এগুলি এমনভাবে রচনা করা হয় যা ঘন ঘন এমনকি সাধারণ ধারণাগুলিকে ঘৃণিতভাবে বাঁকানো এবং ভাঙা ব্যাকরণ এবং শব্দার্থবিদ্যায় রূপান্তরিত করে।

তাই ...

আসল প্রশ্নে। কেউ কি forallকীওয়ার্ডটি পুরোপুরি পরিষ্কার, সরল ইংরাজীতে ব্যাখ্যা করতে পারেন (বা এটি কোথাও উপস্থিত থাকলে এমন স্পষ্ট ব্যাখ্যাটির দিকে ইঙ্গিত করতে পারেন যা আমি মিস করেছি) যে ধরে নিচ্ছে না যে আমি গণিতবিদ ঝাঁপিয়ে পড়েছি?


যুক্ত করতে সম্পাদিত:

নীচে উচ্চ-মানেরগুলি থেকে দুটি স্ট্যান্ড-আউট উত্তর ছিল, তবে দুর্ভাগ্যক্রমে আমি কেবল সেরা হিসাবে বেছে নিতে পারি। নরম্যানের উত্তরটি বিশদ এবং দরকারী ছিল, বিষয়গুলিকে এমনভাবে ব্যাখ্যা করছিল যা কিছু তাত্ত্বিক অনুভূতি দেখিয়েছিল forallএবং একই সাথে আমাকে এর বাস্তবিক কিছু প্রভাবও দেখিয়েছিল । ইয়ারছুর উত্তরঅন্য কোনও অঞ্চল উল্লিখিত (স্কোপড টাইপ ভেরিয়েবল) কভার করেনি এবং কোড এবং একটি জিএইচসিআই অধিবেশন সহ সমস্ত ধারণাটি চিত্রিত করেছেন। উভয়কেই সেরা হিসাবে বেছে নেওয়া সম্ভব হত, আমি করতাম। দুর্ভাগ্যক্রমে আমি পারি না এবং, উভয় উত্তর ঘনিষ্ঠভাবে অনুসন্ধান করার পরে, আমি সিদ্ধান্ত নিয়েছি যে ইয়ারছুর বর্ণনামূলক কোড এবং সংযুক্ত ব্যাখ্যার কারণে নরম্যানের সামান্য কিনারা চলে গেছে। এটি কিছুটা অন্যায়, যদিও সত্যই আমি দু'টি উত্তরই বুঝতে forallপারি যে এটি যখন আমি স্বাক্ষর করে দেখি তখন আমাকে ভয়ঙ্কর বোধের সাথে ছেড়ে যায় না point


7
হাস্কেল উইকি এই বিষয়টিকে বেশ সূক্ষ্ম বান্ধব বলে মনে হচ্ছে।
ঝেগেডুস

উত্তর:


263

একটি কোড উদাহরণ দিয়ে শুরু করা যাক:

foob :: forall a b. (b -> b) -> b -> (a -> b) -> Maybe a -> b
foob postProcess onNothin onJust mval =
    postProcess val
    where
        val :: b
        val = maybe onNothin onJust mval

এই কোডটি সরল হাস্কেল 98-এ সংকলন করে না (সিনট্যাক্স ত্রুটি) key মূল শব্দটিকে সমর্থন করার জন্য এটির এক্সটেনশন প্রয়োজন forall

মূলত, সেখানে 3 বিভিন্ন জন্য সাধারণ ব্যবহার forallশব্দ (বা অন্তত এটা এত বলে মনে হয় ), এবং প্রতিটি নিজস্ব Haskell, এক্সটেনশন রয়েছে: ScopedTypeVariables, RankNTypes/ Rank2Types, ExistentialQuantification

উপরের কোডটি সক্ষম হওয়া উভয়টিরই সাথে একটি সিনট্যাক্স ত্রুটি পায় না, তবে কেবল সক্ষমযুক্ত টাইপ-চেকগুলি ScopedTypeVariables

স্কোপড প্রকারের ভেরিয়েবলগুলি:

স্কোপড প্রকারের ভেরিয়েবলগুলি whereক্লজগুলির অভ্যন্তরে কোডের জন্য প্রকার নির্দিষ্ট করতে সহায়তা করে। এটা তোলে bমধ্যে val :: bহিসাবে একই এক bমধ্যে foob :: forall a b. (b -> b) -> b -> (a -> b) -> Maybe a -> b

একটি বিভ্রান্তিমূলক বিষয় : আপনি শুনতে পাচ্ছেন যে আপনি forallকোনও প্রকার থেকে বাদ দিলে এটি প্রকৃতপক্ষে এখনও স্পষ্টভাবে থাকে। ( নরমানের জবাব থেকে: "সাধারণত এই ভাষাগুলি বহুকোষী ধরণের থেকে ফোরাল বাদ দেয়" )। এই দাবিটি সঠিক, তবে এটি ব্যবহারের forallনয়, অন্যান্য ব্যবহারগুলিকে বোঝায় ScopedTypeVariables

মান-এন-প্রকার:

চলুন শুরু করা যাক এর mayb :: b -> (a -> b) -> Maybe a -> bসমতুল্য mayb :: forall a b. b -> (a -> b) -> Maybe a -> b, কখন বাদেScopedTypeVariables সক্ষম থাকে তা ।

এর অর্থ এটি প্রতিটি aএবং এর জন্য কাজ করে b

বলি আপনি এই জাতীয় কিছু করতে চান।

ghci> let putInList x = [x]
ghci> liftTup putInList (5, "Blah")
([5], ["Blah"])

এর প্রকারটি কী হতে হবে liftTup? এটা liftTup :: (forall x. x -> f x) -> (a, b) -> (f a, f b)। কেন তা দেখতে, আসুন এটি কোড করার চেষ্টা করুন:

ghci> let liftTup liftFunc (a, b) = (liftFunc a, liftFunc b)
ghci> liftTup (\x -> [x]) (5, "Hello")
    No instance for (Num [Char])
    ...
ghci> -- huh?
ghci> :t liftTup
liftTup :: (t -> t1) -> (t, t) -> (t1, t1)

"হুম .. জিএইচসি কেন অনুমান করে যে টিপলটিতে একই ধরণের দুটি থাকতে হবে? আসুন এটি বলি যে তাদের হতে হবে না"

-- test.hs
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
liftTup liftFunc (t, v) = (liftFunc t, liftFunc v)

ghci> :l test.hs
    Couldnt match expected type 'x' against inferred type 'b'
    ...

হুম। তাই এখানে GHC আমাদের আবেদন যাক না liftFuncউপর vকারণ v :: bএবং liftFuncএকটি চায় x। আমরা আমাদের ফাংশনটি এমন কোনও ফাংশন পেতে চাই যা যে কোনও সম্ভাব্য গ্রহণ করে x!

{-# LANGUAGE RankNTypes #-}
liftTup :: (forall x. x -> f x) -> (a, b) -> (f a, f b)
liftTup liftFunc (t, v) = (liftFunc t, liftFunc v)

সুতরাং এটি liftTupযে সবার জন্য কাজ করে xতা নয় , এটি এটি করে যে ফাংশন এটি করে।

অস্তিত্বের পরিমাণ

আসুন একটি উদাহরণ ব্যবহার করুন:

-- test.hs
{-# LANGUAGE ExistentialQuantification #-}
data EQList = forall a. EQList [a]
eqListLen :: EQList -> Int
eqListLen (EQList x) = length x

ghci> :l test.hs
ghci> eqListLen $ EQList ["Hello", "World"]
2

র‌্যাঙ্ক-এন-প্রকার থেকে কীভাবে এটি আলাদা?

ghci> :set -XRankNTypes
ghci> length (["Hello", "World"] :: forall a. [a])
    Couldnt match expected type 'a' against inferred type '[Char]'
    ...

র‌্যাঙ্ক-এন-প্রকারের সাহায্যে forall aআপনার অভিব্যক্তিটি সমস্ত সম্ভাব্য মাপসই করা উচিত a। উদাহরণ স্বরূপ:

ghci> length ([] :: forall a. [a])
0

একটি খালি তালিকা কোনও ধরণের তালিকা হিসাবে কাজ করে।

সুতরাং অস্তিত্ববাদী-রাশিকরণ সঙ্গে, forallগুলি মধ্যে dataসংজ্ঞা মানে, মান অন্তর্ভুক্ত করতে হবে কোন উপযুক্ত ধরন, না এটি আবশ্যক হতে সব উপযুক্ত ধরনের।


ঠিক আছে, আমি আমার ছয় ঘন্টা পেয়েছি এবং এখন আপনার উত্তরটি ডিকোড করতে পারি। :) আপনার এবং নরম্যানের মধ্যে আমি ঠিক যে ধরণের উত্তর খুঁজছিলাম তা পেয়েছি। ধন্যবাদ।
আমার সঠিক মতামতটি ঠিক

2
আসলে, আপনি ScopedTypeVariablesএটির চেয়ে খারাপ দেখায়। আপনি যদি b -> (a -> b) -> Maybe a -> bএই এক্সটেনশানটির সাথে প্রকারটি লিখে থাকেন তবে এটি ঠিক সমান হবে forall a b. b -> (a -> b) -> Maybe a -> b। যাইহোক, যদি আপনি পড়ুন চাই একই b (এবং এটা পরোক্ষভাবে সংখ্যায় আছে) তারপর আপনি স্পষ্টভাবে সংখ্যায় সংস্করণ লিখতে প্রয়োজন। অন্যথায়, STVএটি একটি চূড়ান্ত অনুপ্রবেশকারী এক্সটেনশন হবে।
নামোলো

1
@ নোমিনোলো: আমি বোঝাতে চাইনি ScopedTypeVariables, এবং এটি খারাপ বলে আমি মনে করি না। imho প্রোগ্রামিং প্রক্রিয়াটির জন্য এবং বিশেষত হাস্কেল নতুনদের জন্য এটি একটি খুব সহায়ক সরঞ্জাম এবং এটি উপস্থিত থাকার জন্য আমি কৃতজ্ঞ।
ইয়ারছু

2
এটি একটি পুরানো প্রশ্ন (এবং উত্তর), তবে এটি জিডিএডিটি ব্যবহার করে অস্তিত্বমূলক প্রকারগুলি এমনভাবে প্রকাশ করা যেতে পারে যাতে (আমার কাছে কমপক্ষে) পরিমাণটি বোঝার বিষয়টি আরও সহজ করে দেয় তা প্রতিফলিত করার জন্য এটি আপডেট করার উপযুক্ত।
dfeuer

1
আমি ব্যক্তিগতভাবে মনে করি যে জিডিএডিটি ফর্মটি এর থেকে তার পরিবর্তে অস্তিত্বের স্বরলিপিটি ব্যাখ্যা করার / বোঝার পক্ষে আরও সহজ, তবে আপনি অবশ্যই অন্যথায় ভাবতে নির্মোক্ত।
dfeuer

117

কেউ কি পরিষ্কার, সরল ইংরেজিতে পুরোপুরি কীওয়ার্ডটি ব্যাখ্যা করতে পারে ?

না। (ওয়েল, ডন স্টুয়ার্ট পারে।)

এখানে একটি সাধারণ, স্পষ্ট ব্যাখ্যা বা বাধা রয়েছে forall:

  • এটি একটি কোয়ান্টিফায়ার আপনার সর্বজনীন বা অস্তিত্বের কোয়ান্টিফায়ার দেখতে কমপক্ষে একটি যুক্তি (প্রিকিকেট ক্যালকুলাস) থাকতে হবে। আপনি যদি প্রাক্কলিত ক্যালকুলাসটি কখনও দেখেননি বা কোয়ান্টিফায়ারগুলিতে স্বাচ্ছন্দ্য বোধ করেন না (এবং আমি পিএইচডি যোগ্যতা অর্জনকারী শিক্ষার্থীদের দেখেছি যারা আরামদায়ক নয়) তবে আপনার জন্য, এর সহজ কোনও ব্যাখ্যা নেই forall

  • এটি এক প্রকার কোয়ান্টিফায়ার। আপনি যদি সিস্টেম এফ না দেখে থাকেন এবং পলিমারফিক টাইপগুলি লেখার জন্য কিছু অনুশীলন অর্জন করেন, তবে আপনি forallবিভ্রান্তিকর সন্ধান করতে যাচ্ছেন । হাস্কেল বা এমএল-এর অভিজ্ঞতা যথেষ্ট নয়, কারণ সাধারণত এই ভাষাগুলি বহুতল forallথেকে বাদ দেওয়া হয় it (মনে মনে, এটি একটি ভাষা-ডিজাইনের ভুল)

  • বিশেষত হাস্কেল-তে forallএমনভাবে ব্যবহার করা হয় যা আমি বিভ্রান্তিকর মনে করি। (আমি কোনও ধরণের তাত্ত্বিক নই, তবে আমার কাজটি আমাকে প্রচুর টাইপের তত্ত্বের সংস্পর্শে এনেছে এবং আমি এতে যথেষ্ট স্বাচ্ছন্দ্য বোধ করি।) আমার জন্য, বিভ্রান্তির মূল উত্স হ'ল forallকোন প্রকারের এনকোড করতে ব্যবহৃত হয় আমি নিজেই লিখতে পছন্দ করব exists। এটি কোয়ান্টিফায়ার এবং তীরগুলির সাথে জড়িত একটি জটিল বিভক্ত ধরণের আইসমোরফিজমের দ্বারা ন্যায়সঙ্গত এবং আমি যখনই এটি বুঝতে চাই তখন আমাকে জিনিসগুলি সন্ধান করতে হবে এবং নিজেই আইসোমরফিজমটি কাজ করতে হবে।

    আপনি যদি টাইপ আইসোমরফিজমের ধারণাটি নিয়ে স্বাচ্ছন্দ্য বোধ করেন না বা যদি আপনার কাছে টাইপ আইসোমর্ফিজম সম্পর্কে চিন্তাভাবনা না থাকে তবে এই ব্যবহারটি forallআপনাকে স্তিমিত করতে চলেছে।

  • যদিও সাধারণ ধারণাটি forallসর্বদা একই থাকে (একটি ধরণের ভেরিয়েবল প্রবর্তনের জন্য বাধ্য), বিভিন্ন ব্যবহারের বিশদটি উল্লেখযোগ্যভাবে পরিবর্তিত হতে পারে। বৈচিত্রগুলি ব্যাখ্যা করার জন্য অনানুষ্ঠানিক ইংরেজি খুব ভাল সরঞ্জাম নয়। কী চলছে তা সত্যি বুঝতে আপনার কিছু গাণিতিক প্রয়োজন। এক্ষেত্রে প্রাসঙ্গিক গণিতটি বেঞ্জামিন পিয়ার্সের প্রবর্তনীয় পাঠ্য প্রকার এবং প্রোগ্রামিং ভাষাগুলিতে পাওয়া যাবে , এটি একটি খুব ভাল বই।

আপনার নির্দিষ্ট উদাহরণ হিসাবে,

  • runST আপনার মাথা আঘাত করা উচিত । উচ্চ-স্তরের প্রকারগুলি (একটি তীরের বাম থেকে ফোড়াল) বন্যের মধ্যে খুব কমই পাওয়া যায়। আমি আপনাকে প্রবর্তিত কাগজটি পড়তে উত্সাহিত করি runST: "অলস কার্যকরী রাষ্ট্রের থ্রেডস" । এটি সত্যই একটি ভাল কাগজ, এবং এটি আপনাকে runSTবিশেষত ধরণের এবং সাধারণভাবে উচ্চ-পদমর্যাদার ধরণের জন্য আরও ভালতর অন্তর্দৃষ্টি দেয় । ব্যাখ্যাটি বেশ কয়েকটি পৃষ্ঠায় নিয়েছে, এটি খুব ভালভাবে সম্পন্ন হয়েছে এবং আমি এটি এখানে ঘনীভূত করার চেষ্টা করব না।

  • বিবেচনা

    foo :: (forall a. a -> a) -> (Char,Bool)
    bar :: forall a. ((a -> a) -> (Char, Bool))

    যদি আমি কল করি bar, আমি কেবল aআমার পছন্দ মতো যে কোনও ধরণের বাছাই করতে পারি এবং আমি এটিকে টাইপ থেকে টাইপ aকরতে পারি a। উদাহরণস্বরূপ, আমি ফাংশন (+1)বা ফাংশনটি পাস করতে পারি reverse। আপনি forall"আমি এখন টাইপটি বেছে নেব" বলে বলে ভাবতে পারেন । (ধরণের বাছাইয়ের প্রযুক্তিগত শব্দটি তাত্ক্ষণিক

    কল করার fooক্ষেত্রে বিধিনিষেধগুলি আরও বেশি কঠোর: যুক্তিটি একটি বহুকর্মী ফাংশন হতে foo হবে । যে ধরনের সঙ্গে, শুধুমাত্র ফাংশন আমি পাস করতে পারেন fooহয় idবা ফাংশন যে সবসময় অপসারী বা ত্রুটি মত undefined। কোনো কারণ ছাড়াই যে foo, forallতীর-এর বাঁদিক থেকে যাতে এর কলার fooআমি বাছাই করতে হবে তা না aহয়-বরং এটা বাস্তবায়ন এর fooযে বাছাই কি পায় aহয়। কারণ forallতীরের বাম দিকে যেমন রয়েছে তীরের চেয়ে উপরে bar, তত্ক্ষণা কল সাইটে নয় বরং ফাংশনের শরীরে ঘটে।

সারাংশ: একটি সম্পূর্ণ ব্যাখ্যা forallশব্দ গণিত প্রয়োজন এবং একমাত্র যিনি গণিত চর্চিত হয়েছে বোঝা যাবে। এমনকি আংশিক ব্যাখ্যাও গণিত ছাড়াই বোঝা শক্ত। তবে আমার আংশিক, অ-গণিতের ব্যাখ্যাগুলি কিছুটা সহায়তা করে। লঞ্চবারি এবং পাইটন জোন্স পড়তে যান runST!


সংযোজন: জারগন "উপরে", "নীচে", "এর বামে"। পাঠ্য পদ্ধতিতে প্রবন্ধগুলি লিখিত হয় এবং বিমূর্ত-বাক্য গঠন গাছের সাথে করণীয় এর সাথে এগুলির কোনও সম্পর্ক নেই । বিমূর্ত সিনট্যাক্সে, একটি forallটাইপ ভেরিয়েবলের নাম নেয় এবং তারপরে ফোরালের "নীচে" একটি সম্পূর্ণ টাইপ রয়েছে। একটি তীর দুটি ধরণের (আর্গুমেন্ট এবং ফলাফলের ধরণ) নেয় এবং একটি নতুন ধরণের (ফাংশনের ধরণ) গঠন করে। আর্গুমেন্টের ধরণটি তীরের "বাম দিকে"; এটি বিমূর্ত-সিনট্যাক্স গাছের তীর বাম শিশু।

উদাহরণ:

  • মধ্যে forall a . [a] -> [a], forall তীর উপরে আছে; তীর বাম কি হয় [a]

  • ভিতরে

    forall n f e x . (forall e x . n e x -> f -> Fact x f) 
                  -> Block n e x -> f -> Fact x f

    প্রথম বন্ধনীর ধরণটিকে "একটি তীরের বাম দিকে একটি ফোড়াল" বলা হবে। (আমি যে অপটিমাইজারটিতে কাজ করছি তাতে আমি এ জাতীয় ধরণের ব্যবহার করছি))


আসলে আমি এটি সম্পর্কে চিন্তা না করে উপরের / নীচে / বামে পেয়েছি। আমি একজন ডুলার্ড, হ্যাঁ, তবে একজন পুরাতন দুলার্ড যাকে আগে এই জিনিসগুলির সাথে কুস্তি করতে হয়েছিল। (অন্যদের মধ্যে একটি এএসএন .১ সংকলক লেখা ;;) সংশোধনের জন্য ধন্যবাদ যদিও।
আমার সঠিক মতামতটি

12
@ জাস্ট ধন্যবাদ তবে আমি উত্তরোত্তর জন্য লিখছি আমি একাধিক প্রোগ্রামার দৌড়ে এসেছি যারা মনে করে যে forall a . [a] -> [a]তীরটির বাঁদিকে ফোড়ালটি রয়েছে।
নরম্যান রামসে

ঠিক আছে, আপনার উত্তরটি বিশদভাবে অবলম্বন করে এখন, আমি আপনাকে আন্তরিক ধন্যবাদ জানাতে চাই নরম্যান, আমার হৃদয়ের নীচ থেকে। এখন প্রচুর ক্লিকের সাথে প্রচুর স্টাফ পড়েছে, এবং যে জিনিসগুলি আমি এখনও বুঝতে পারি না তা কমপক্ষে আমি বুঝতে পারি যে আমি এটি বোঝার জন্য বোঝাতে চাই নি এবং forallএই পরিস্থিতিতে কার্যকরভাবে, রেখার মধ্য দিয়ে যাব will গোলমাল। আপনি যে কাগজের সাথে লিঙ্ক করেছেন সেটির উপরে আমি নজর রাখব (পাশাপাশি লিঙ্কটির জন্য ধন্যবাদ!) এবং দেখুন এটি আমার বোধগম্য অঞ্চলে আছে কিনা। যশ।
আমার সঠিক মতামতটি

10
আমি বামে পড়েছি এবং আমি আক্ষরিক, বাম দিকে তাকালাম। সুতরাং আপনি "পার্স ট্রি" না বলা পর্যন্ত এটি আমার পক্ষে অত্যন্ত অস্পষ্ট ছিল।
পল নাথান

পিয়ার্সের বইটির পয়েন্টারকে ধন্যবাদ। এটি সিস্টেম এফ এর একটি খুব স্পষ্ট ব্যাখ্যা রয়েছে কারণ এটি কেন existsকখনও প্রয়োগ করা হয়নি তা ব্যাখ্যা করে । (এটি সিস্টেম এফের অংশ নয়!) হাস্কেল-এ সিস্টেম এফের কিছু অংশ অন্তর্নিহিত করা হয়েছে, তবে forallএমন একটি জিনিস যা পুরোপুরি গালিগুজের নীচে ছড়িয়ে যায় না। দেখে মনে হচ্ছে যেন তারা হিন্দি-মিলনার দিয়ে শুরু করেছিল, যা forallঅন্তর্নিহিত হওয়ার অনুমতি দেয় এবং তারপরে আরও শক্তিশালী ধরণের সিস্টেমের পক্ষে বেছে নিয়েছিল, যারা আমাদের মধ্যে FOL এর 'forall' অধ্যয়ন করেছে এবং সেখানে উপস্থিত রয়েছে তাদের বিভ্রান্ত করে।
T_S_

50

আমার মূল উত্তর:

কেউ কি পুরোপুরি স্পষ্ট, সরল ইংরেজিতে পুরোপুরি কীওয়ার্ডটি ব্যাখ্যা করতে পারে?

নরম্যান ইঙ্গিত হিসাবে, টাইপ তত্ত্ব থেকে প্রযুক্তিগত শব্দ একটি পরিষ্কার, সরল ইংরেজী ব্যাখ্যা দেওয়া খুব কঠিন। আমরা সকলেই চেষ্টা করছি।

'ফোরাল' সম্পর্কে মনে রাখার জন্য কেবল একটি জিনিস রয়েছে: এটি কিছু প্রকারের সাথে টাইপ করে । একবার বুঝতে পারলে সবকিছু মোটামুটি সহজ। এটি টাইপ স্তরের 'ল্যাম্বদা' (বা 'লেট' এর একটি রূপ) এর সমতুল্য - নরম্যান রামসে তাঁর দুর্দান্ত উত্তরে এই একই ধারণার সুযোগটি প্রকাশ করতে "বাম" / "উপরে" ধারণাটি ব্যবহার করে ।

'ফোড়াল' এর বেশিরভাগ ব্যবহার খুব সহজ, এবং আপনি এটি জিএইচসি ব্যবহারকারী ম্যানুয়াল, এস 7.৮ . বিশেষত ' ফোরাল ' এর নেস্টেড ফর্মগুলিতে দুর্দান্ত এস .8..8..5 এ প্রবর্তন করতে পারেন ।

হাস্কেল-এ, আমরা সাধারণত প্রকারের জন্য বাইন্ডারটি ছেড়ে দিই, যখন প্রকারটি সর্বজনীনভাবে মীমাংসিত হয়, যেমন:

length :: forall a. [a] -> Int

সমান:

length :: [a] -> Int

এটাই.

যেহেতু আপনি এখন টাইপের ভেরিয়েবলগুলিকে কিছুটা স্কাইন্ডে বেঁধে রাখতে পারেন , আপনার প্রথম উদাহরণের মতো শীর্ষ স্তরের (" সর্বজনীন পরিমাণযুক্ত ") ব্যতীত স্কোপগুলি থাকতে পারে , যেখানে টাইপ ভেরিয়েবল কেবলমাত্র ডেটা কাঠামোর মধ্যে দৃশ্যমান। এটি লুকানো ধরণের (" অস্তিত্বের প্রকার ") এর জন্য মঞ্জুরি দেয় । অথবা আমাদের বাইন্ডিংগুলিতে নির্বিচারে বাসা বাঁধতে পারে ("র‌্যাঙ্ক এন টাইপস")।

টাইপ সিস্টেমগুলি গভীরভাবে বুঝতে, আপনাকে কিছু জার্গোন শিখতে হবে। এটি কম্পিউটার বিজ্ঞানের প্রকৃতি। তবে, উপরের মতো সাধারণ ব্যবহারগুলি মান স্তরের 'লেট' দিয়ে সাদৃশ্যের মাধ্যমে স্বজ্ঞাতভাবে উপলব্ধি করতে সক্ষম হওয়া উচিত। একটি দুর্দান্ত ভূমিকা হ'ল লঞ্চবারি এবং পাইটন জোন্স


4
প্রযুক্তিগতভাবে, কখন সক্ষম হয় তার length :: forall a. [a] -> Intসমতুল্য নয় । যখন সেখানে থাকে, এটি এর ধারাটিতে প্রভাব ফেলে (যদি এটি থাকে) এবং এতে নামযুক্ত টাইপের ভেরিয়েবলের অর্থ পরিবর্তন করে । length :: [a] -> IntScopedTypeVariablesforall a.lengthwherea
ইয়ারছু

2
প্রকৃতপক্ষে. ScopedTypeVariables গল্পটি কিছুটা জটিল করে তোলে।
ডন স্টুয়ার্ট

3
@ ডোনস্টয়ার্ট, আপনার ব্যাখ্যাতে "এটি কিছু ধরণের সাথে টাইপগুলি বেঁধে রাখতে পারে" এটি আরও ভাল শব্দযুক্ত হিসাবে "এটি কিছু স্কোপের সাথে টাইপ ভেরিয়েবলগুলি বাঁধতে পারে"?
রোমিল্ডো

31

তারা এই অনুমানের সাথে ঘন হয়ে আছে যে আমি পৃথক পৃথক গণিত, বিভাগের তত্ত্ব বা বিমূর্ত বীজগণিতের যে কোনও শাখায় এই সপ্তাহে জনপ্রিয়। (আমি যদি আবার "প্রয়োগের তথ্যের জন্য কাগজের সাথে পরামর্শ করুন" শব্দটি না পড়ি তবে খুব শীঘ্রই এটি হবে।)

এর, এবং সাধারণ প্রথম-আদেশ যুক্তি সম্পর্কে কী? সার্বজনীন পরিমিতকরণেরforall প্রসঙ্গে বেশ স্পষ্টভাবে , এবং সেই প্রসঙ্গে অস্তিত্ববাদী শব্দটি আরও বেশি অর্থবোধ করে , যদিও কোনও কীওয়ার্ড থাকলে এটি কম বিশ্রী হবে । কোয়ান্টিফিকেশন কার্যকরভাবে সর্বজনীন বা অস্তিত্বশীল কিনা তার উপর নির্ভর করে কোয়ান্টিফায়ার সম্পর্কিত স্থানে যেখানে ভেরিয়েবলগুলি কোনও ফাংশন তীরের কোন দিকে ব্যবহার করা হয় এবং এটি কিছুটা বিভ্রান্তিকর।exists

সুতরাং, যদি এটি সাহায্য না করে, বা যদি আপনি কেবল প্রতীকী যুক্তি পছন্দ না করেন তবে আরও কার্যকরী প্রোগ্রামিং-ইশ দৃষ্টিকোণ থেকে আপনি টাইপ ভেরিয়েবলগুলি কেবল ফাংশনটিতে (অন্তর্ভুক্ত) টাইপ পরামিতি হিসাবে ভাবতে পারেন । এই অর্থে প্রকারের পরামিতিগুলি গ্রহণ করা কার্যক্রমে যে কোনও কারণেই মূলধন ল্যাম্বদা ব্যবহার করে রীতিগতভাবে লেখা হয়, যা আমি এখানে লিখব /\

সুতরাং, idফাংশনটি বিবেচনা করুন :

id :: forall a. a -> a
id x = x

আমরা এটিকে ল্যাম্বডাস হিসাবে পুনরায় লিখতে পারি, স্বাক্ষরের প্রকারের বাইরে "টাইপ প্যারামিটার" সরিয়ে নিয়ে এবং ইনলাইন প্রকারের টীকাগুলি যুক্ত করতে পারি:

id = /\a -> (\x -> x) :: a -> a

এখানে একই জিনিস করা হয়েছে const :

const = /\a b -> (\x y -> x) :: a -> b -> a

সুতরাং তোমার bar ফাংশন কিছু হতে পারে:

bar = /\a -> (\f -> ('t', True)) :: (a -> a) -> (Char, Bool)

নোট করুন যে barআর্গুমেন্ট হিসাবে প্রদত্ত ফাংশনের ধরণের উপর নির্ভর করেbar তার ধরণের পরামিতির । পরিবর্তে আপনার যদি এরকম কিছু ছিল কিনা তা বিবেচনা করুন:

bar2 = /\a -> (\f -> (f 't', True)) :: (a -> a) -> (Char, Bool)

এখানে bar2কিছু ধরণের ফাংশন প্রয়োগ করা হচ্ছে Char, তাই দিচ্ছেbar2 অন্য কোনও ধরণের পরামিতি দেওয়াChar একটি ধরণের ত্রুটির কারণ হবে।

অন্যদিকে, এখানে fooদেখতে কী হতে পারে তা এখানে :

foo = (\f -> (f Char 't', f Bool True))

বিপরীতে bar, fooআসলে কোনও ধরণের পরামিতি গ্রহণ করে না! এটি একটি ফাংশন নেয় যা নিজেই একটি টাইপ প্যারামিটার নেয়, তারপরে সেই ফাংশনটি দুটি পৃথকভাবে প্রয়োগ করে ধরণের ।

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


পোস্ট স্ক্রিপ্টাম : সম্ভবত আপনি ভাবতে পারেন - এখন আমরা টাইপ পরামিতিগুলি গ্রহণের ফাংশনগুলির বিষয়ে ভাবছি, কেন আমরা সেই পরামিতিগুলির সাথে টাইপ সিগনেচারের চেয়ে আরও আকর্ষণীয় কিছু করতে পারি না? উত্তর আমরা করতে পারি যে!

একটি ফাংশন যা লেবেলের সাথে টাইপ ভেরিয়েবলগুলি রাখে এবং একটি নতুন টাইপ দেয় তা হ'ল টাইপ কনস্ট্রাক্টর , যা আপনি এই জাতীয় কিছু লিখতে পারেন:

Either = /\a b -> ...

তবে আমাদের পুরোপুরি নতুন স্বরলিপি প্রয়োজন, কারণ এই জাতীয় ধরণের রচনাটি Either a bযেমন ইতিমধ্যে " Eitherএই পরামিতিগুলিতে ফাংশনটি প্রয়োগ করুন" বলে প্রস্তাবিত ।

অন্যদিকে, একটি ফাংশন যা তার ধরণের প্যারামিটারগুলিতে "প্যাটার্ন মেলে" বাছাই করে, বিভিন্ন ধরণের জন্য বিভিন্ন মান ফিরিয়ে দেয়, এটি একটি টাইপ শ্রেণীর একটি পদ্ধতি/\উপরের আমার সিনট্যাক্সের সামান্য বিস্তৃতি এরকম কিছু প্রস্তাব দেয়:

fmap = /\ f a b -> case f of
    Maybe -> (\g x -> case x of
        Just y -> Just b g y
        Nothing -> Nothing b) :: (a -> b) -> Maybe a -> Maybe b
    [] -> (\g x -> case x of
        (y:ys) -> g y : fmap [] a b g ys 
        []     -> [] b) :: (a -> b) -> [a] -> [b]

ব্যক্তিগতভাবে, আমি মনে করি আমি হাস্কেলের আসল বাক্য গঠনকেই প্রাধান্য দিচ্ছি ...

একটি ফাংশন যা তার ধরণের পরামিতিগুলিকে "প্যাটার্নের সাথে মেলে" এবং একটি নির্বিচারে ফিরিয়ে দেয়, বিদ্যমান টাইপটি হ'ল এক ধরণের পরিবার বা কার্যকরী নির্ভরতা - পূর্ববর্তী ক্ষেত্রে এটি এমনকি ইতিমধ্যে একটি ফাংশন সংজ্ঞা মত একটি দুর্দান্ত কাজ দেখায়।


1
একটি আকর্ষণীয় এখানে নিতে। এটি আমাকে সমস্যার উপর আক্রমণের আরও একটি কোণ দেয় যা দীর্ঘ মেয়াদে ফলদায়ক প্রমাণ করতে পারে। ধন্যবাদ।
আমার সঠিক মতামতটি

@ কেনিটিএম: বা λএই বিষয়টির জন্য, তবে জিএইচসি-র ইউনিকোড সিনট্যাক্স এক্সটেনশন সমর্থন করে না কারণ λ একটি চিঠি , এটি একটি দুর্ভাগ্যজনক সত্য যা অনুমানের সাথে আমার অনুমানযুক্ত বড়-ল্যাম্বডা বিমূর্তনের ক্ষেত্রেও প্রযোজ্য। সুতরাং সাথে /\ সাদৃশ্য \ । আমি মনে করি আমি কেবল ব্যবহার করতে পারতাম তবে আমি প্রাক্কলিত ক্যালকুলাস এড়ানোর চেষ্টা করছিলাম ...
সিএ ম্যাকক্যান

29

এখানে সরল পদগুলির একটি দ্রুত এবং নোংরা ব্যাখ্যা যা আপনি ইতিমধ্যে পরিচিত হওয়ার সম্ভাবনা রয়েছে।

forallশব্দ সত্যিই শুধুমাত্র মধ্যে Haskell ওয়ান ওয়ে ব্যবহার করা হয়। আপনি যখন দেখবেন তখন সর্বদা একই জিনিস বোঝায়।

সর্বজনীন পরিমাণ

একটি সার্বজনীন পরিমাণযুক্ত টাইপ ফর্মের এক প্রকার forall a. f a। এই ধরণের একটি মান একটি ফাংশন হিসাবে ভাবা যেতে পারে যা কোনও প্রকারকে a তার আর্গুমেন্ট হিসাবে গ্রহণ করে এবং টাইপের মান প্রদান করে f a। হাস্কেল ব্যতীত এই ধরণের আর্গুমেন্টগুলি টাইপ সিস্টেমের দ্বারা সুস্পষ্টভাবে পাস করা হয়। এই "ফাংশন" আপনাকে কোনও মানই দেয় যে কোনও ধরণেরই তা গ্রহণ করে না, সুতরাং মানটি বহুকীর্ণ

উদাহরণস্বরূপ, প্রকারটি বিবেচনা করুন forall a. [a]। এই ধরণের একটি মান অন্য ধরণের নেয় aএবং আপনাকে একই ধরণের উপাদানগুলির তালিকা ফিরিয়ে দেয় a। অবশ্যই একমাত্র কার্যকর বাস্তবায়ন আছে। এটি আপনাকে খালি তালিকা aদিতে হবে কারণ একেবারে যে কোনও ধরণের হতে পারে। খালি তালিকাটি একমাত্র তালিকার মান যা এর উপাদান ধরণের পলিমারফিক (যেহেতু এটির কোনও উপাদান নেই)।

বা টাইপ forall a. a -> a। এই জাতীয় ফাংশনের কলার একটি প্রকার aএবং প্রকারের মান উভয়ই সরবরাহ করে a। বাস্তবায়নের পরে একই ধরণের একটি মান ফেরত দিতে হয় a। আবার একমাত্র সম্ভাব্য বাস্তবায়ন আছে। এটি প্রদত্ত একই মানটি ফেরত দিতে হবে।

অস্তিত্বের পরিমাণ

যদি হাস্কেল সেই স্বরলিপিটি সমর্থন করে তবে একটি অস্তিত্বযুক্ত পরিমাণযুক্ত প্রকারের ফর্মটি থাকবে exists a. f a। এই ধরণের একটি মান একটি প্রকার এবং প্রকারের মান সমন্বিত একটি জোড় (বা "পণ্য") হিসাবে ভাবা যেতে পারে ।af a

উদাহরণস্বরূপ, আপনার যদি টাইপের মান থাকে তবে আপনার কাছে কোনও ধরণের exists a. [a]উপাদানগুলির একটি তালিকা রয়েছে। এটি যে কোনও ধরণের হতে পারে তবে এটি কী তা আপনি যদি না জানেন তবে এমন একটি তালিকাতে আপনি অনেক কিছু করতে পারেন। আপনি এটিকে বিপরীত করতে পারেন, বা আপনি উপাদানগুলির সংখ্যা গণনা করতে পারেন, বা অন্য কোনও তালিকা অপারেশন করতে পারেন যা উপাদানগুলির ধরণের উপর নির্ভর করে না।

ঠিক আছে, তাই এক মিনিট অপেক্ষা করুন। কেন হ্যাসেল forallনীচের মতো "অস্তিত্বের" প্রকারকে বোঝায়?

data ShowBox = forall s. Show s => SB s

এটি বিভ্রান্তিকর হতে পারে, তবে এটি সত্যই ডেটা নির্মাতার প্রকারের বর্ণনা দিচ্ছে SB:

SB :: forall s. Show s => s -> ShowBox

একবার তৈরি হয়ে গেলে, আপনি ShowBoxদুটি জিনিসের সমন্বয়ে ধরণের মানটির কথা ভাবতে পারেন । এটি টাইপের sমান সহ এক প্রকারের s। অন্য কথায়, এটি একটি অস্তিত্বযুক্ত পরিমাণযুক্ত প্রকারের মান। ShowBoxসত্যিই লেখা যেতে পারে exists s. Show s => s, যদি হাস্কেল সেই স্বাক্ষরকে সমর্থন করে।

runST এবং বন্ধুরা

দেওয়া আছে, এই কিভাবে পৃথক?

foo :: (forall a. a -> a) -> (Char,Bool)
bar :: forall a. ((a -> a) -> (Char, Bool))

প্রথমে নেওয়া যাক bar। এটি একটি টাইপ aএবং টাইপ একটি ফাংশন লাগে a -> a, এবং টাইপ একটি মান উত্পাদন করে (Char, Bool)। আমরা Intহিসাবে চয়ন করতে aএবং এটি টাইপ একটি ফাংশন দিতে পারেInt -> Int উদাহরণস্বরূপ । তবে fooআলাদা। এটির প্রয়োজন যে বাস্তবায়নটি fooআমরা যে ফাংশনটি দিয়েছি তাতে এটি যে কোনও ধরণের পছন্দ করতে সক্ষম হয়। সুতরাং একমাত্র ফাংশনটি আমরা যুক্তিযুক্তভাবে এটি দিতে পারি id

আমাদের এখনকার ধরণের অর্থটি মোকাবেলা করতে সক্ষম হওয়া উচিত runST :

runST :: forall a. (forall s. ST s a) -> a

সুতরাং runSTটাইপের একটি মান উত্পাদন করতে সক্ষম হতে হবে a, যাই হোক না কেন আমরা যে ধরণেরই থাকি a। এটি করতে, এটি টাইপের একটি আর্গুমেন্ট ব্যবহার করে forall s. ST s aযা অবশ্যই কোনওরকম উত্পাদন করতে হবে a। আরও কি এটি ধরণের মান উত্পাদন করতে সক্ষম হবেa বাস্তবায়নের runSTযেভাবে সিদ্ধান্ত গ্রহণের সিদ্ধান্ত নেয় তা নির্বিশেষে এটিs

ঠিক আছে, তাই কি? সুবিধাটি হ'ল এটি কলকারীকে এই ক্ষেত্রে বাধা দেয় runSTযে প্রকারটি প্রকারটি aমোটেই জড়িত করতে পারে না sST s [s]উদাহরণস্বরূপ আপনি এটিকে কোনও ধরণের মান পাস করতে পারবেন না । বাস্তবে এর অর্থ যা হ'ল তা হ'ল বাস্তবায়ন runSTটাইপের মান সহ মিউটেশন সম্পাদন করতে পারে s। প্রকারটি গ্যারান্টি দেয় যে এই রূপান্তরটি বাস্তবায়নের জন্য স্থানীয় runST

প্রকারটি র‌্যাঙ্ক -২ পলিমারফিক ধরণেরrunST উদাহরণ, কারণ এর যুক্তির ধরণটিতে একটি পরিমাণ রয়েছে । উপরের প্রকারটিও র‌্যাঙ্ক ২-এর মতো একটি সাধারণ বহুকর্মী টাইপ, র‌্যাঙ্ক -১ হয়, তবে এটি যদি পদক্ষেপের ধরণের নিজস্ব কমান্ডিফায়ার সহ পলিমারফিক হতে হয় তবে এটি র‌্যাঙ্ক -২ হয় । এবং যদি কোনও ফাংশন র‌্যাঙ্ক -২ টি আর্গুমেন্ট নেয় তবে তার ধরণটি র‌্যাঙ্ক -৩, ইত্যাদি। সাধারণভাবে, এমন এক ধরণের যা বহুরূপী আর্গুমেন্ট নেয় র‌্যাঙ্কটি থাকে ।forallfoobarforallnn + 1


11

কেউ কি পুরোপুরি কীওয়ার্ডটি সম্পূর্ণ পরিষ্কার, সরল ইংরাজীতে ব্যাখ্যা করতে পারেন (বা এটি যদি কোথাও উপস্থিত থাকে তবে এমন একটি স্পষ্ট ব্যাখ্যা যা আমি মিস করেছি) তা ধরে নিতে পারে না যে আমি গণিতবিদ ঝাঁপিয়ে পড়েছি?

আমি চেষ্টা করতে এবং ব্যাখ্যা করতে যাচ্ছি মাত্র অর্থ এবং সম্ভবত প্রয়োগটি forallহ্যাস্কেল এবং এর ধরণের সিস্টেমের প্রসঙ্গে।

তবে আপনি বুঝতে পারার আগে আমি রানার বর্জনসনের " সীমাবদ্ধতা মুক্তি, লিবার্টিজ কনস্ট্রেন " শিরোনামের একটি খুব অ্যাক্সেসযোগ্য এবং সুন্দর আলোচনায় আপনাকে পরিচালিত করতে চাই । এই বক্তব্যটি বাস্তব জগতের ব্যবহারের উদাহরণের সাথে স্ক্যালায় উদাহরণগুলি পূর্ণ, যেমনটি এই বিবৃতি সমর্থন করে না, যদিও এর উল্লেখ নেই forall। আমি forallনীচে দৃষ্টিভঙ্গি ব্যাখ্যা করার চেষ্টা করব ।

                CONSTRAINTS LIBERATE, LIBERTIES CONSTRAIN

নিম্নলিখিত বিবরণ নিয়ে এগিয়ে যাওয়ার জন্য এই বিবৃতিটি হজম করা এবং বিশ্বাস করা খুব গুরুত্বপূর্ণ, তাই আমি আপনাকে বক্তব্যটি দেখার (এটির কমপক্ষে কিছু অংশ) দেখার জন্য অনুরোধ করছি।

এখন একটি খুব সাধারণ উদাহরণ, হ্যাস্কেল টাইপ সিস্টেমের ভাব প্রকাশ করা এই ধরণের স্বাক্ষর:

foo :: a -> a

বলা হয় যে এই ধরণের স্বাক্ষর প্রদানের পরে, কেবলমাত্র একটি ফাংশন যা এই ধরণের সন্তুষ্ট করতে পারে এবং তা হ'ল identityফাংশন বা যা বেশি জনপ্রিয় id

আমার হাস্কেল শেখার প্রথম পর্যায়ে, আমি সর্বদা নীচের ফাংশনগুলি নিয়ে ভাবতাম:

foo 5 = 6

foo True = False

তারা উভয়ই উপরের ধরণের স্বাক্ষরটি সন্তুষ্ট করে, তবে কেন হাস্কেল লোকেরা দাবি করবে যে এটি idএকা যা প্রকারের স্বাক্ষরকে সন্তুষ্ট করে?

কারণ forallস্বাক্ষর প্রকারে একটি অন্তর্নিহিত লুকানো আছে। আসল প্রকারটি হ'ল:

id :: forall a. a -> a

সুতরাং, এখন ফিরে আসি বিবৃতিটিতে: সীমাবদ্ধতাগুলি মুক্তি দেয়, স্বাধীনতার সীমাবদ্ধতা

এটি টাইপ সিস্টেমে অনুবাদ করে, এই বিবৃতিটি হয়ে ওঠে:

প্রকার স্তরে একটি সীমাবদ্ধতা, শব্দ স্তরে একটি স্বাধীনতা হয়ে ওঠে

এবং

প্রকার স্তরে একটি স্বাধীনতা, শব্দ স্তরে একটি সীমাবদ্ধ হয়ে যায়


আসুন আমরা প্রথম বিবৃতিটি প্রমাণ করার চেষ্টা করি:

প্রকার স্তরে একটি প্রতিবন্ধকতা ..

সুতরাং আমাদের টাইপ স্বাক্ষরে একটি সীমাবদ্ধতা রাখা

foo :: (Num a) => a -> a

শব্দ পর্যায়ে একটি স্বাধীনতা হয়ে ওঠে আমাদের এগুলি সমস্ত লেখার স্বাধীনতা বা নমনীয়তা দেয়

foo 5 = 6
foo 4 = 2
foo 7 = 9
...

aঅন্য কোনও টাইপক্লাস ইত্যাদির সাথে সীমাবদ্ধ করে একই জিনিসটি লক্ষ্য করা যায়

সুতরাং এখন এই ধরণের স্বাক্ষর কি: foo :: (Num a) => a -> aঅনুবাদ করে:

a , st a -> a, a  Num

এটি অস্তিত্বযুক্ত পরিমাপক হিসাবে পরিচিত, যা সেখানে অনুবাদ করে এমন কিছু উদাহরণ রয়েছেa যার জন্য কোনও ফাংশন যখন কোনও কিছু খাওয়ানো হয়a হয় তখন একই ধরণের কিছু ফিরে আসে এবং সেই উদাহরণগুলি সমস্ত সংখ্যার সেটের সাথে সম্পর্কিত।

অতএব আমরা একটি সীমাবদ্ধতা যোগ করতে দেখতে পাচ্ছি (এটি aসংখ্যার সেট অন্তর্ভুক্ত হওয়া উচিত), একাধিক সম্ভাব্য বাস্তবায়ন করতে শব্দ স্তরটি মুক্ত করে।


এখন দ্বিতীয় বিবৃতিতে আসছেন এবং একটি যা আসলে এর ব্যাখ্যা বহন করে forall:

প্রকার স্তরে একটি স্বাধীনতা, শব্দ স্তরে একটি সীমাবদ্ধ হয়ে যায়

সুতরাং এখন টাইপ স্তরে ফাংশনটি স্বাধীন করি:

foo :: forall a. a -> a

এখন এটি অনুবাদ করে:

a , a -> a

যার অর্থ এই ধরণের স্বাক্ষরের বাস্তবায়ন এমন হওয়া উচিত যা এটি a -> aসমস্ত পরিস্থিতিতে রয়েছে circumstances

সুতরাং এখন এটি শব্দ পর্যায়ে আমাদের সীমাবদ্ধ করতে শুরু করে। আমরা আর লিখতে পারি না

foo 5 = 7

কারণ আমরা যদি aএকটি হিসাবে রাখি তবে এই বাস্তবায়ন সন্তুষ্ট হবে না Boolaএকটি Charবা একটি [Char]বা কাস্টম ডেটাটাইপ হতে পারে । সমস্ত পরিস্থিতিতে এটি একই ধরণের কিছু ফেরত দেওয়া উচিত। প্রকারের স্তরে এই স্বাধীনতা হ'ল ইউনিভার্সাল কোয়ান্টিফিকেশন হিসাবে পরিচিত এবং এটি কেবলমাত্র একমাত্র ক্রিয়া যা এটি সন্তুষ্ট করতে পারে

foo a = a

যা সাধারণত identityফাংশন হিসাবে পরিচিত


অতএব টাইপ স্তরে forallএমন একটি libertyযাঁর আসল উদ্দেশ্যটি constrainএকটি নির্দিষ্ট প্রয়োগের জন্য পদ স্তরের।


9

এই কীওয়ার্ডটির বিভিন্ন ব্যবহার হওয়ার কারণ হ'ল এটি আসলে কমপক্ষে দুটি পৃথক ধরণের সিস্টেম এক্সটেনশনে ব্যবহৃত হয়: উচ্চ-স্তরের ধরণ এবং অস্তিত্ব।

'ফোরাল' একই সাথে উভয় ক্ষেত্রে সিনট্যাক্সের যথাযথ বিট কেন তা ব্যাখ্যা করার চেষ্টা করার চেয়ে এই দুটি বিষয় আলাদাভাবে পড়ার এবং বোঝার পক্ষে সবচেয়ে ভাল।


3

কীভাবে অস্তিত্বের অস্তিত্ব?

অস্তিত্ববাদী-রাশিকরণ সঙ্গে, forallমধ্যে গুলি dataসংজ্ঞা মানে, মান অন্তর্ভুক্ত করতে হবে কোন উপযুক্ত ধরন, না এটি আবশ্যক হতে সব উপযুক্ত ধরনের। - ইয়াছিরুর উত্তর

কেন একটি ব্যাখ্যা foralldataসংজ্ঞায় বেশ isomorphic হয় (exists a. a)(সিউডো-Haskell,) খুঁজে পাওয়া যেতে পারে উইকিবই-এর "Haskell, / Existentially সংখ্যায় ধরনের"

নীচে একটি সংক্ষিপ্ত ভারব্যাটিম সংক্ষিপ্তসার রয়েছে:

data T = forall a. MkT a -- an existential datatype
MkT :: forall a. a -> T -- the type of the existential constructor

প্যাটার্ন-ম্যাচিং / ডিকনস্ট্রাকচারিংয়ের সময় MkT xকী কী x?

foo (MkT x) = ... -- -- what is the type of x?

xযে কোনও ধরণের হতে পারে (যেমন বলা হয়েছে forall), এবং সুতরাং এটি টাইপটি হ'ল:

x :: exists a. a -- (pseudo-Haskell)

অতএব, নিম্নলিখিতটি isomorphic:

data T = forall a. MkT a -- an existential datatype
data T = MkT (exists a. a) -- (pseudo-Haskell)

ফোরাল মানে ফোরাল

আমার এই সমস্ত সম্পর্কে সহজ ব্যাখ্যা, এটি " forallসত্যিকার অর্থে 'সকলের জন্য" "। করতে একটি গুরুত্বপূর্ণ পার্থক্য প্রভাব forallউপর সংজ্ঞা ফাংশন বনাম আবেদন

একটি forallমানে সংজ্ঞা মান বা ক্রিয়াটির বহুকোষী হতে হবে।

যদি সংজ্ঞায়িত জিনিসটি একটি বহুকর্মী মান হয় , তবে এর অর্থ হ'ল মানটি অবশ্যই উপযুক্ত সকলের জন্য বৈধ হওয়া উচিত a, যা বেশ সীমাবদ্ধ।

যদি সংজ্ঞায়িত জিনিসটি একটি বহুকোষী ফাংশন হয় , তবে এর অর্থ হ'ল ফাংশনটি অবশ্যই উপযুক্ত সকলের জন্য বৈধ হওয়া উচিত a, যা এই সীমাবদ্ধ নয় কারণ কেবলমাত্র ফাংশনটি পলিমারফিক হিসাবে বোঝায় না যে পরামিতি প্রয়োগ করা হচ্ছে পলিমারফিক হতে হবে। অর্থাৎ যদি ফাংশন সব জন্য বৈধ a, তবে বিপরীতভাবে কোনো উপযুক্ত aকরা যাবে প্রয়োগ ফাংশন। তবে প্যারামিটারের ধরণটি কেবল একবার ফাংশন সংজ্ঞাতে বেছে নেওয়া যেতে পারে।

যদি কোনও forallফাংশন প্যারামিটারের ধরণের (যেমন, ক Rank2Type) অভ্যন্তরে থাকে তবে এর অর্থ হ'ল প্রয়োগকৃত পরামিতিটি সত্যিকারের বহুবিন্দুযুক্ত হতে হবে, forallমানে সংজ্ঞাটির ধারণার সাথে সামঞ্জস্যপূর্ণ হওয়া বহুবর্ষীয়। এই ক্ষেত্রে, প্যারামিটারের ধরণটি ফাংশন সংজ্ঞায় একাধিকবার বাছাই করা যেতে পারে ( "এবং নরম্যান দ্বারা নির্দেশিত হিসাবে ফাংশন প্রয়োগের দ্বারা নির্বাচিত হয় )"

অতএব, যে কারণে অস্তিত্ববাদের dataসংজ্ঞা পারবেন কোন a কারণ তথ্য কন্সট্রাকটর একটি বহুরুপী হয় ফাংশন :

MkT :: forall a. a -> T

এমকেটি ধরণের :: a -> *

যার অর্থ aকোনওটি ফাংশনে প্রয়োগ করা যেতে পারে। যেমনটি বলা যায়, একটি বহুভুজনীয় মান :

valueT :: forall a. [a]

মান মান টাইপ :: a

যার মানে সংজ্ঞা valueT এর বহুরুপী হতে হবে। এই ক্ষেত্রে, সমস্ত ধরণের valueTখালি তালিকা হিসাবে সংজ্ঞায়িত করা যেতে পারে []

[] :: [t]

পার্থক্য

যদিও এর জন্য অর্থটি forallসামঞ্জস্যপূর্ণ ExistentialQuantificationএবং RankNType, অস্তিত্বের একটি পার্থক্য রয়েছে যেহেতু নির্মাতা dataপ্যাটার্ন মিলের ক্ষেত্রে ব্যবহার করা যেতে পারে। যেমনটি ভূত ব্যবহারকারী নির্দেশিকায় নথিভুক্ত হয়েছে :

প্যাটার্ন মেলানোর সময়, প্রতিটি প্যাটার্ন ম্যাচ প্রতিটি অস্তিত্বের ধরণের ভেরিয়েবলের জন্য একটি নতুন, স্বতন্ত্র, প্রকার প্রবর্তন করে। এই ধরণেরগুলি অন্য কোনও ধরণের সাথে একীভূত করা যায় না, বা প্যাটার্ন মিলের সুযোগ থেকে তারা পালাতে পারে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.