হাস্কেল: টাইপক্লাস বনাম একটি ফাংশন পাস করে passing


16

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

class Eq a where 
  (==)                  :: a -> a -> Bool

এবং অন্যান্য ফাংশনগুলিতে এটিকে যুক্তি যুক্ত করতে নির্দেশ করতে অবশ্যই এটির উদাহরণ হতে হবে Eq:

elem                    :: (Eq a) => a -> [a] -> Bool

আমরা কি কেবল elemটাইপক্লাস ব্যবহার না করে আমাদের ফাংশনটি সংজ্ঞায়িত করতে পারি এবং পরিবর্তে কোনও ফাংশন আর্গুমেন্টটি পাস করি যা কাজ করে?


2
একে অভিধান পাসিং বলে। টাইপক্লাসের সীমাবদ্ধতাগুলি অন্তর্নিহিত আর্গুমেন্ট হিসাবে ভাবতে পারেন।
পোস্টক্যাট

2
আপনি এটি করতে পারতেন তবে কোনও ফাংশন পাস করতে না পারার পক্ষে এটি স্পষ্টতই অনেক বেশি সুবিধাজনক এবং কেবল টাইপের উপর নির্ভর করে এটি "মানক" ব্যবহার করুন।
রবিন জিগমন্ড

2
আপনি এটি যেমন রাখা যেতে পারে, হ্যাঁ। তবে আমি যুক্তি দিয়েছি যে কমপক্ষে আরও একটি গুরুত্বপূর্ণ সুবিধা রয়েছে: পলিমর্ফিক ফাংশনগুলি লেখার ক্ষমতা যা কোনও ধরণের ক্ষেত্রে কাজ করে যা একটি নির্দিষ্ট "ইন্টারফেস" বা বৈশিষ্ট্যগুলির সেটকে প্রয়োগ করে। আমার মনে হয় টাইপক্লাসের প্রতিবন্ধকতাগুলি খুব পরিষ্কারভাবে এমনভাবে প্রকাশ করে যাতে অতিরিক্ত ফাংশন যুক্তিগুলি পাস না করে। বিশেষত (শোকের সাথে অন্তর্নিহিত) "আইন" এর কারণে যা অনেক টাইপচ্লাসকে সন্তুষ্ট করতে হয়। একটি Monad mবাধ্যতা ধরনের অতিরিক্ত ফাংশন আর্গুমেন্ট ক্ষণস্থায়ী চেয়ে আমার আরো বলেছেন a -> m aএবং m a -> (a -> m b) -> m b
রবিন জিগমন্ড


1
TypeApplicationsএক্সটেনশান আপনাকে অন্তর্নিহিত যুক্তি স্পষ্ট করার সুবিধা দেয়। (==) @Int 3 5তুলনা 3এবং 5বিশেষত Intমান হিসাবে । আপনি @Int-স্পেসিফিক Intতুলনা ফাংশন না করে টাইপ-নির্দিষ্ট সমতা ফাংশনগুলির অভিধানের একটি কী হিসাবে ভাবতে পারেন ।
চিপনার

উত্তর:


19

হ্যাঁ. একে বলা হয় "অভিধান পাসিং স্টাইল"। কখনও কখনও আমি যখন বিশেষত কৌতুকপূর্ণ কাজগুলি করি তখন আমাকে একটি টাইপক্লাস স্ক্র্যাপ করে অভিধানে পরিণত করা দরকার, কারণ অভিধান পাস করা আরও শক্তিশালী 1 , তবে প্রায়শই বেশ জটিল, ধারণাগতভাবে সহজ কোডটি বেশ জটিল দেখায়। আমি কখনও কখনও এমন ভাষাগুলিতে অভিধান পাসিং স্টাইল ব্যবহার করি যা টাইপক্লাসগুলি অনুকরণ করার জন্য হাস্কেল নয় (তবে শিখেছি যে এটি সাধারণত মনে হয় তেমন ধারণা নয়) great

অবশ্যই, যখনই অভিব্যক্তিগত শক্তির মধ্যে পার্থক্য হয়, সেখানে বাণিজ্য বন্ধ থাকে। আপনি যদি কোনও প্রদত্ত এপিআই আরও বেশি উপায়ে ব্যবহার করতে পারেন তবে এটি ডিপিএস ব্যবহার করে লেখা থাকলে, আপনি না পারলে এপিআই আরও তথ্য পায়। Data.Setবাস্তবে এটি প্রদর্শিত করার একটি উপায় রয়েছে , যা Ordপ্রতি টাইপের জন্য কেবল একটি অভিধান রয়েছে তা নির্ভর করে । Setদোকানে তার উপাদান অনুযায়ী সাজানো Ord, এবং যদি আপনি এক অভিধান সঙ্গে একটি সেট সংগ্রহ করতে, এবং তারপর একটি উপাদান একটি ভিন্ন ব্যবহার ঢোকানো, যেমন ডিপিএস সঙ্গে সম্ভব হবে, আপনি ভাঙতে পারে Setএর পরিবর্তিত এবং এটি বিপর্যস্ত হতে পারে। এই স্বতন্ত্রতা সমস্যাটি অল্প অস্তিত্ব ব্যবহার করে প্রশমিত করা যেতে পারেঅভিধানটি চিহ্নিত করতে টাইপ করুন, তবে, আবার এপিআইতে বিরক্তিকর জটিলতার জন্য ব্যয় করুন। এটি এপিআইতেও একইভাবে প্রদর্শিত হয় Typeable

স্বতন্ত্রতা বিট খুব প্রায়ই আসে না। টাইপচ্লাসে যা দুর্দান্ত তা আপনার জন্য কোড রচনা। উদাহরণ স্বরূপ,

catProcs :: (i -> Maybe String) -> (i -> Maybe String) -> (i -> Maybe String)
catProcs f g = f <> g

এটিতে দুটি "প্রসেসর" লাগে যা একটি ইনপুট নেয় এবং একটি আউটপুট দেয় এবং তাদের সমঝোতা করে চ্যাপ্টা করে ডিপিএসে Nothingএই জাতীয় কিছু লিখতে হবে:

catProcs f g = (<>) (funcSemi (maybeSemi listSemi)) f g

আমরা এটির পুনরায় যে প্রকারটি ব্যবহার করছি তা আমাদের মূলত বানান করতে হয়েছিল, যদিও আমরা ইতিমধ্যে স্বাক্ষর প্রকারে এটি বানান করেছি, এমনকি এটি অপ্রয়োজনীয় কারণ সংকলকটি ইতিমধ্যে সমস্ত প্রকারগুলি জানে। Semigroupকোনও ধরণের প্রদত্ত একটি নির্মাণের একমাত্র উপায় থাকার কারণে , সংকলকটি এটি আপনার জন্য করতে পারে। সংযুক্তকারীদের মতো আপনি যখন অনেকগুলি প্যারামিটারিক দৃষ্টান্তগুলি সংজ্ঞায়িত করতে এবং আপনার ধরণের কাঠামোটি আপনার জন্য গণনা করতে শুরু করেন তখন এটির একটি "যৌগিক আগ্রহ" টাইপ প্রভাব রয়েছে Data.Functor.*এবং এটি দুর্দান্ত প্রভাব ফেলবে deriving viaযেখানে আপনি মূলত সমস্ত জিনিস পেতে পারেন আপনার জন্য রচিত আপনার প্রকারের "স্ট্যান্ডার্ড" বীজগণিত কাঠামো।

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

-

1 ইউ nless আপনি ব্যবহার reflectionযা কেস তারা ক্ষমতায় সমতুল্য হয়ে - কিন্তু reflectionব্যবহার করা কষ্টকর হতে পারে।



আমি ডিপিএসের মাধ্যমে প্রকাশিত ফান্ডেপগুলিতে খুব আগ্রহী। আপনি কি এই বিষয়ে কিছু স্মরণযোগ্য সংস্থান সম্পর্কে জানেন? যাইহোক, খুব বোধগম্য ব্যাখ্যা।
বব

@ বব, অফহ্যান্ড নয়, তবে এটি একটি আকর্ষণীয় অনুসন্ধান হবে। এটি সম্পর্কে একটি নতুন প্রশ্ন জিজ্ঞাসা করতে পারেন?
লুচি

5

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

elemBy :: (a -> a -> Bool) -> a -> [a] -> Bool
elemBy _ _ [] = False
elemBy eq x (y:ys) = eq x y || elemBy eq x ys

কলিং elemBy (==) x xsএখন সমান elem x xs। এবং এই নির্দিষ্ট ক্ষেত্রে, আপনি আরও এক ধাপ এগিয়ে যেতে পারেন: eqপ্রতিবার একই প্রথম যুক্তি রয়েছে, যাতে আপনি এটি প্রয়োগের জন্য কলারের দায়িত্ব করতে পারেন এবং এটি শেষ করে দিতে পারেন:

elemBy2 :: (a -> Bool) -> [a] -> Bool
elemBy2 _ [] = False
elemBy2 eqx (y:ys) = eqx y || elemBy2 eqx ys

কলিং elemBy2 (x ==) xsএখন সমান elem x xs

...অপেক্ষা কর. ঠিক আছে any। (এবং প্রকৃতপক্ষে স্ট্যান্ডার্ড লাইব্রেরিতেelem = any . (==) ,।)


এএফআইইউ অভিধান পাসিং হ'ল এনকোডিং প্রকারের ক্লাসগুলির জন্য স্কালার পদ্ধতি। এই অতিরিক্ত আর্গুমেন্ট হিসাবে ঘোষিত হতে পারে implicitএবং সংকলক সুযোগগুলি থেকে আপনার জন্য এটি ইনজেক্ট করবে।
মিচিড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.