কমপক্ষে 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 লোমশ আইনকে l
2 টি দুর্দান্ত পয়েন্টফ্রি সমতুল্য করে:
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 লাইব্রেরি রাখার বিষয়ে আমার আগের উদ্বেগগুলি থেকে অনেকটা চাপ নেয়।
lens
প্যাকেজের সবচেয়ে সমৃদ্ধ কার্যকারিতা এবং ডকুমেন্টেশন রয়েছে, সুতরাং আপনি যদি এর জটিলতা এবং নির্ভরতাগুলি মনে না করেন তবে এটি যাওয়ার উপায়।