লেন্স, ফলক্লেবেলস, ডেটা-অ্যাকসেসর - কাঠামোর অ্যাক্সেস এবং মিউটেশনের জন্য কোন লাইব্রেরিটি ভাল


173

রেকর্ডের ক্ষেত্রগুলি অ্যাক্সেস এবং পরিচালনা করার জন্য কমপক্ষে তিনটি জনপ্রিয় গ্রন্থাগার রয়েছে। আমি যেগুলি সম্পর্কে জানি সেগুলি হ'ল ডেটা-অ্যাক্সেসর, fclabels এবং লেন্স।

ব্যক্তিগতভাবে আমি ডেটা অ্যাক্সেসর দিয়ে শুরু করেছি এবং আমি এখন সেগুলি ব্যবহার করছি। তবে সম্প্রতি হ্যাসেল-ক্যাফেতে fclabels উচ্চতর হওয়ার বিষয়ে একটি মতামত ছিল।

সুতরাং আমি এই তিনটি (এবং আরও বেশি) গ্রন্থাগারের তুলনায় আগ্রহী interested


3
আজকের হিসাবে, lensপ্যাকেজের সবচেয়ে সমৃদ্ধ কার্যকারিতা এবং ডকুমেন্টেশন রয়েছে, সুতরাং আপনি যদি এর জটিলতা এবং নির্ভরতাগুলি মনে না করেন তবে এটি যাওয়ার উপায়।
মডিউলার

উত্তর:


200

কমপক্ষে 4 টি গ্রন্থাগার রয়েছে যা আমি লেন্স সরবরাহ সম্পর্কে সচেতন।

লেন্সের ধারণাটি এটি আইসোমোরফিক কিছু সরবরাহ করে

data Lens a b = Lens (a -> b) (b -> a -> a)

দুটি ফাংশন সরবরাহ করে: একটি গেটর এবং একটি সেটার

get (Lens g _) = g
put (Lens _ s) = s

তিনটি আইনের সাপেক্ষে:

প্রথমত, আপনি যদি কিছু রাখেন তবে আপনি এটি আবার বের করতে পারেন

get l (put l b a) = b 

দ্বিতীয়টি হচ্ছে এবং সেটিং করা উত্তরটি পরিবর্তন করে না

put l (get l a) a = a

এবং তৃতীয়ত, দু'বার রাখা একবার রাখার মতোই বা দ্বিতীয়টি যে দ্বিতীয় বার জিতবে।

put l b1 (put l b2 a) = put l b1 a

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

এই লাইব্রেরিগুলির মধ্যে অনেকগুলি উপরে অতিরিক্ত সংযুক্তকারীগুলির একটি গোছাও সরবরাহ করে এবং সাধারণত কিছু রেকর্ড প্রকারের ক্ষেত্রগুলির জন্য স্বয়ংক্রিয়ভাবে লেন্স তৈরি করতে টেম্পলেট হ্যাশেল যন্ত্রপাতি রয়েছে।

এই বিষয়টি মনে রেখে আমরা বিভিন্ন বাস্তবায়নের দিকে ফিরে যেতে পারি:

বাস্তবায়নের

fclabels

fclabels সম্ভবত লেন্সের গ্রন্থাগারগুলির সম্পর্কে খুব সহজে যুক্তিযুক্ত কারণ a :-> bএটি উপরের ধরণে সরাসরি অনুবাদ করা যেতে পারে। এটি এমন একটি বিভাগ উদাহরণ সরবরাহ করে (:->)যার জন্য এটি কার্যকর কারণ এটি আপনাকে লেন্স রচনা করতে দেয়। এটি একটি আইনহীন Pointপ্রকারও সরবরাহ করে যা এখানে ব্যবহৃত লেন্সগুলির ধারণাটি সাধারণীকরণ করে এবং আইসোমরফিজমের সাথে কাজ করার জন্য কিছু নদীর গভীরতানির্ণয় করে।

গ্রহণের ক্ষেত্রে একটি বাধা fclabelsহ'ল মূল প্যাকেজটিতে টেম্পলেট-হেস্কেল নদীর গভীরতানির্ণয় অন্তর্ভুক্ত থাকে, সুতরাং প্যাকেজটি হাস্কেল 98 নয়, এবং এটির জন্য (মোটামুটি বিতর্কিত) TypeOperatorsএক্সটেনশনও প্রয়োজন।

ডেটা-অ্যাকসেসর

[সম্পাদনা: data-accessorআর এই উপস্থাপনাটি ব্যবহার করে না, তবে এর মতো ফর্মটিতে চলে গেছে data-lens। যদিও আমি এই ভাষ্যটি রাখছি]]

ডেটা-অ্যাকসেসর চেয়ে কিছুটা বেশি জনপ্রিয় fclabelsকারণ এটি অংশে হয় Haskell, 98. তবে অভ্যন্তরীণ উপস্থাপনা তার পছন্দ আমার মুখের মধ্যে একটি সামান্য বিট তোলা তোলে।

Tএটি কোন ধরণের লেন্স উপস্থাপন করতে ব্যবহার করে তা অভ্যন্তরীণভাবে সংজ্ঞায়িত করা হয়েছে

newtype T r a = Cons { decons :: a -> r -> (a, r) }

ফলস্বরূপ, getকোনও লেন্সের মানের জন্য, আপনাকে অবশ্যই 'এ' যুক্তিটির জন্য একটি অপরিবর্তিত মান জমা দিতে হবে! এটি আমাকে অবিশ্বাস্যরূপে কুশ্রী এবং অ্যাডহক বাস্তবায়ন হিসাবে আঘাত করে।

এটি বলেছিল, হেনিং আপনার জন্য পৃথক ' ডেটা-অ্যাক্সেসর-টেম্পলেট ' প্যাকেজে স্বয়ংক্রিয়ভাবে অ্যাকসেসরগুলি তৈরি করতে টেম্পলেট-হ্যাশেল প্লাম্বিং অন্তর্ভুক্ত করেছে ।

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

লেন্স

এর পরে, লেন্স প্যাকেজ রয়েছে, যা পর্যবেক্ষণ করে যে একটি লেন্স দুটি রাষ্ট্রের মনাদের মধ্যে একটি রাষ্ট্রীয় মনড হোমোর্ফিজম সরবরাহ করতে পারে, যেমন মোনাদ সমকামী হিসাবে সরাসরি লেন্সগুলি নির্দিষ্ট করে ।

যদি এটি প্রকৃতপক্ষে এর লেন্সগুলির জন্য কোনও প্রকার সরবরাহ করতে বিরক্ত করে তবে তাদের মতো একটি র‌্যাঙ্ক -2 টাইপ থাকে:

newtype Lens s t = Lens (forall a. State t a -> State s a)

ফলস্বরূপ, আমি বরং এই পদ্ধতির পছন্দ করি না, কারণ এটি অকারণে আপনাকে হাস্কেল ৯৮ এর বাইরে ফেলে রাখে (যদি আপনি বিমূর্তে আপনার লেন্স সরবরাহ করতে চান তবে) এবং আপনাকে Categoryলেন্সের জন্য উদাহরণ থেকে বঞ্চিত করবে , যা আপনাকে দেয় তাদের রচনা .। বাস্তবায়নের জন্য মাল্টি-প্যারামিটার ধরণের শ্রেণিও প্রয়োজন।

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

তদ্ব্যতীত, প্রারম্ভে বর্ণিত পার্শ্ব-শর্তগুলির এই ফর্মটিতে সত্যিই একটি সুন্দর অভিব্যক্তি নেই। 'Fclabels' এর মতো এটি সরাসরি প্রধান প্যাকেজে রেকর্ড টাইপের জন্য স্বয়ংক্রিয়ভাবে লেন্স তৈরির জন্য টেমপ্লেট-হ্যাস্কেল পদ্ধতি সরবরাহ করে।

Categoryউদাহরণের অভাব , বারোক এনকোডিং এবং প্রধান প্যাকেজে টেমপ্লেট-হেস্কেলের প্রয়োজনীয়তার কারণে এটি আমার স্বল্পতম প্রিয় বাস্তবায়ন।

তথ্য-লেন্স

[সম্পাদনা করুন: 1.8.0 পর্যন্ত, এগুলি কমোনাদ-ট্রান্সফরমার প্যাকেজ থেকে ডেটা-লেন্সে স্থানান্তরিত হয়েছে]

আমার data-lensপ্যাকেজটি স্টোর কমোনেডের শর্তে লেন্স সরবরাহ করে ।

newtype Lens a b = Lens (a -> Store b a)

কোথায়

data Store b a = Store (b -> a) b

এটি প্রসারিত সমান

newtype Lens a b = Lens (a -> (b, b -> a))

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

এই প্রতিনিধিত্বের জন্য একটি দুর্দান্ত তাত্ত্বিক ন্যায়সঙ্গততাও রয়েছে, কারণ 'প্রতিক্রিয়াটির শুরুতে বর্ণিত 3 আইন পূরণ করে এমন' লেন্স 'মানগুলির উপসেটটি হ'ল লেন্সগুলি যার জন্য মোড়ানো ফাংশনটি স্টোর কমোনেডের জন্য' কমোনাদ কয়লাজেব্রা ' । এটি একটি লেন্সের জন্য 3 লোমশ আইনকে l2 টি দুর্দান্ত পয়েন্টফ্রি সমতুল্য করে:

extract . l = id
duplicate . l = fmap l . l

এই পদ্ধতির প্রথম সুপরিচিত এবং রাসেল কোনর এর বর্ণনা করা হয়েছিল Functorহয় Lensযেমন Applicativeহয় Biplate: পেশ করা হচ্ছে Multiplate এবং ছিল একটি উদ্ভাবনের উপর ভিত্তি করে নিয়ে ব্লগ লিখেছিল জেরেমি গিবনস দ্বারা।

এটিতে কঠোরভাবে লেন্সের সাথে কাজ করার জন্য বেশ কয়েকটি সংযুক্তকারী এবং পাত্রে কিছু স্টক লেন্স যেমন অন্তর্ভুক্ত রয়েছে Data.Map

সুতরাং ল ( data-lensএকটি প্যাকেজটির Categoryবিপরীতে lenses) লেন্সগুলি হ্যাস্কেল 98 (বিপরীতে fclabels/ lenses) হয়, বুদ্ধিমান হয় (এর শেষ প্রান্তের মত নয় data-accessor) এবং কিছুটা আরও কার্যকর বাস্তবায়ন data-lens-fdসরবরাহ করে , বাইরে পদক্ষেপ নিতে ইচ্ছুকদের জন্য মোনাডস্টেটের সাথে কাজ করার কার্যকারিতা সরবরাহ করে হাস্কেল 98 এর, এবং টেমপ্লেট-হেস্কেল যন্ত্রপাতি এখন উপলব্ধ data-lens-template

6/28/2012 আপডেট করুন: অন্যান্য লেন্স বাস্তবায়ন কৌশল

আইসমোরিজম লেন্সসমূহ

বিবেচনা করার মতো আরও দুটি লেন্স এনকোডিং রয়েছে। প্রথমটি কোনও লেন্সকে ক্ষেত্রের মান এবং অন্য কিছুর সাথে মান ভেঙে ফেলার উপায় হিসাবে দেখার জন্য একটি দুর্দান্ত তাত্ত্বিক উপায় দেয়।

আইসোমরফিজমের জন্য এক ধরণের দেওয়া হয়েছে

data Iso a b = Iso { hither :: a -> b, yon :: b -> a }

যেমন বৈধ সদস্যরা সন্তুষ্ট hither . yon = id, এবংyon . hither = id

আমরা এর সাথে একটি লেন্স উপস্থাপন করতে পারি:

data Lens a b = forall c. Lens (Iso a (b,c))

এগুলি লেন্সগুলির অর্থ সম্পর্কে চিন্তা করার উপায় হিসাবে প্রাথমিকভাবে দরকারী এবং আমরা অন্যান্য লেন্সগুলি ব্যাখ্যা করার জন্য যুক্তিযুক্ত সরঞ্জাম হিসাবে তাদের ব্যবহার করতে পারি।

ভ্যান লাথোভেন লেন্স

আমরা এমন লেন্সগুলির মডেল করতে পারি যেগুলি সেগুলি দিয়ে তৈরি করা যেতে পারে (.)এবং idএমনকি Categoryউদাহরণ ব্যবহার না করে

type Lens a b = forall f. Functor f => (b -> f b) -> a -> f a

আমাদের লেন্স জন্য টাইপ হিসাবে।

তারপরে লেন্স সংজ্ঞায়িত করা যেমন সহজ:

_2 f (a,b) = (,) a <$> f b

এবং আপনি নিজের জন্য যাচাই করতে পারেন যে ফাংশন রচনাটি লেন্স রচনা।

আমি সম্প্রতি লিখেছি যে আপনি কীভাবে ভ্যান লাথোভেন লেন্সগুলিকে আরও সাধারণ করতে পারেন লেন্স পরিবারগুলি যাতে ক্ষেত্রের ধরণের পরিবর্তন করতে পারে, কেবল এই স্বাক্ষরকে সাধারণীকরণের মাধ্যমে

type LensFamily a b c d = forall f. Functor f => (c -> f d) -> a -> f b

এর দুর্ভাগ্যজনক পরিণতি রয়েছে যে লেন্স সম্পর্কে কথা বলার সর্বোত্তম উপায় হ'ল র‌্যাঙ্ক 2 পলিমারফিজম ব্যবহার করা, তবে লেন্স সংজ্ঞা দেওয়ার সময় আপনার সেই স্বাক্ষরটি সরাসরি ব্যবহার করার দরকার নেই।

Lensআমি উপরে বর্ণিত _2আসলে একটি হয় LensFamily

_2 :: Functor f => (a -> f b) -> (c,a) -> f (c, b)

আমি একটি গ্রন্থাগার লিখেছি যাতে লেন্স, লেন্স পরিবার এবং গেটরস, সেটার, ভাঁজ এবং ট্র্যাভারসাল সহ অন্যান্য সাধারণীকরণ অন্তর্ভুক্ত রয়েছে। এটি lensপ্যাকেজ হিসাবে হ্যাকারে উপলব্ধ ।

আবার, এই পদ্ধতির একটি বড় সুবিধা হ'ল গ্রন্থাগার রক্ষণাবেক্ষণকারীরা Functor f => (b -> f b) -> a -> f aনির্দিষ্ট ধরণের 'ক' এবং 'বি' টাইপের সাথে কেবলমাত্র ফাংশন সরবরাহ করে, যে কোনও প্রকার লেন্স লাইব্রেরি নির্ভরতা ব্যয় না করে আপনার লাইব্রেরিতে এই স্টাইলে লেন্স তৈরি করতে পারে । এটি গ্রহণের ব্যয়কে হ্রাস করে।

যেহেতু আপনাকে নতুন লেন্স সংজ্ঞায়িত করার জন্য প্যাকেজটি ব্যবহার করার দরকার নেই, সুতরাং এটি হ্যাশেল 98 লাইব্রেরি রাখার বিষয়ে আমার আগের উদ্বেগগুলি থেকে অনেকটা চাপ নেয়।


28
আমি এর আশাবাদী পদ্ধতির জন্য fclabels পছন্দ করি:->
টেনার


10
হাসেল 1998 কি সামঞ্জস্যপূর্ণ হওয়া গুরুত্বপূর্ণ? কারণ এটি সংকলক উন্নয়ন সহজ করে তোলে? এবং এর পরিবর্তে আমাদের হাস্কেল ২০১০ সম্পর্কে কথা বলা উচিত না?
ইয়ারছু

55
ওহ না! আমি এর মূল লেখক data-accessor, এবং তারপরে আমি এটিকে হেনিংয়ের হাতে দিয়েছি এবং মনোযোগ দেওয়া বন্ধ করি। a -> r -> (a,r)উপস্থাপনা আমার অস্বস্তিকর করে তোলে, এবং আমার মূল বাস্তবায়ন শুধু আপনার মত ছিল Lensপ্রকার। Heeennnninngg !!
luqui

5
ইয়ারছু: এটি বেশিরভাগ ক্ষেত্রে তাই আপনার লাইব্রেরিতে জিএইচসি ছাড়া অন্য কোনও সংকলকের সাথে কাজ করার সুযোগ থাকতে পারে। অন্য কারও কাছে হাস্কেল টেমপ্লেট নেই। 2010 এখানে প্রাসঙ্গিক কিছু যুক্ত করে না।
এডওয়ার্ড কেএমইটিটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.