আমি বহুভুতের সূচকগুলি বর্তমান দৃশ্যে সংরক্ষণ করতে পারতাম, বহুভুতের টানা পয়েন্টের সূচক এবং প্রতিবার এটি প্রতিস্থাপন করতে পারি। তবে এই পদ্ধতির স্কেল হয় না - যখন কম্পোজিশনের মাত্রা 5 এবং আরও চলে যায়, বয়লারপ্লেটটি অসহনীয় হয়ে উঠবে।
আপনি একদম ঠিক বলেছেন, আপনি যদি বয়লারপ্লেটটি পেতে না পারেন তবে এই পদ্ধতির স্কেল হয় না । বিশেষত, একটি ক্ষুদ্রতর সাব-পার্ট সহ পুরো নতুন দৃশ্য তৈরির জন্য বয়লারপ্লেট পরিবর্তিত হয়েছে। তবে, অনেকগুলি কার্যকরী ভাষা এই ধরণের নেস্টেড স্ট্রাকচার ম্যানিপুলেশন: লেন্সগুলির সাথে কাজ করার জন্য একটি কাঠামো সরবরাহ করে।
একটি লেন্স মূলত অপরিবর্তনীয় ডেটার জন্য একটি গেটর এবং সেটার। একটি লেন্স বৃহত্তর কাঠামোর কিছু ছোট অংশের উপর দৃষ্টি নিবদ্ধ করে। একটি লেন্স দেওয়া হয়েছে, এটির সাথে দুটি জিনিস আপনি করতে পারেন - আপনি বৃহত্তর কাঠামোর একটি মানের ছোট অংশটি দেখতে পারেন , বা আপনি একটি বৃহত কাঠামোর একটি মানের ছোট অংশটি একটি নতুন মানকে সেট করতে পারেন । উদাহরণস্বরূপ, ধরুন আপনার কাছে একটি লেন্স রয়েছে যা তালিকার তৃতীয় আইটেমটির উপরে দৃষ্টি নিবদ্ধ করে:
thirdItemLens :: Lens [a] a
এই ধরণের অর্থ বৃহত্তর কাঠামো জিনিসগুলির একটি তালিকা এবং ছোট সাব-পার্ট সেই জিনিসগুলির মধ্যে একটি। এই লেন্স দেওয়া, আপনি তালিকার তৃতীয় আইটেমটি দেখতে এবং সেট করতে পারেন:
> view thirdItemLens [1, 2, 3, 4, 5]
3
> set thirdItemLens 100 [1, 2, 3, 4, 5]
[1, 2, 100, 4, 5]
লেন্সগুলি কার্যকর হওয়ার কারণ হ'ল এগুলি গেটার এবং সেটারগুলির প্রতিনিধিত্বকারী মান এবং আপনি অন্যান্য মানগুলিকে একইভাবে বিমূর্ত করতে পারেন। আপনি ফাংশনগুলি করতে পারেন যা লেন্সগুলি ফেরত দেয়, উদাহরণস্বরূপ এমন একটি listItemLens
ফাংশন যা একটি সংখ্যা নেয় এবং একটি তালিকার তৃতীয় আইটেমটি n
দেখলে একটি লেন্স দেয় returns n
অতিরিক্তভাবে, লেন্সগুলি রচনা করা যেতে পারে :
> firstLens = listItemLens 0
> thirdLens = listItemLens 2
> firstOfThirdLens = lensCompose firstLens thirdLens
> view firstOfThirdLens [[1, 2], [3, 4], [5, 6], [7, 8]]
5
> set firstOfThirdLens 100 [[1, 2], [3, 4], [5, 6], [7, 8]]
[[1, 2], [3, 4], [100, 6], [7, 8]]
প্রতিটি লেন্স ডেটা স্ট্রাকচারের এক স্তরকে অতিক্রম করার জন্য আচরণকে আবদ্ধ করে। এগুলিকে একত্রিত করে, আপনি একাধিক স্তরের জটিল কাঠামোকে অনুসরণ করার জন্য বয়লারপ্লেটটি অপসারণ করতে পারেন। উদাহরণস্বরূপ, ধরুন scenePolygonLens i
যে i
আপনি একটি দৃশ্যের পঞ্চম বহুভুজকে polygonPointLens n
দেখেছেন nth
এবং একটি বহুভুজের পয়েন্টটি দেখছেন, আপনি যেমন একটি সম্পূর্ণ দৃশ্যে যত্নশীল ঠিক সেই নির্দিষ্ট পয়েন্টটির দিকে মনোনিবেশ করার জন্য আপনি একটি লেন্স নির্মাতা তৈরি করতে পারেন:
scenePointLens i n = lensCompose (polygonPointLens n) (scenePolygonLens i)
এখন ধরুন যে কোনও ব্যবহারকারী বহুভুজ 14 এর 3 পয়েন্টটি ক্লিক করেন এবং 10 পিক্সেল ডানদিকে সরান। আপনি আপনার দৃশ্যের মত আপডেট করতে পারেন:
lens = scenePointLens 14 3
point = view lens currentScene
newPoint = movePoint 10 0 point
newScene = set lens newPoint currentScene
এটিতে দৃশ্যের ভিতরে প্রবেশ ও আপডেট করার জন্য সমস্ত বয়লারপ্লেট রয়েছে lens
যা আপনাকে বিন্দুতে পরিবর্তন করতে চান তা আপনাকেই যত্নবান হতে হবে। আপনি লেন্সের মাধ্যমে লক্ষ্যটির ভিউ আপডেট করার জন্য lensTransform
কোনও লেন্স, একটি লক্ষ্য এবং একটি ফাংশন গ্রহণ করে এমন একটি ফাংশন দিয়ে আপনি এটি আরও বিমূর্ত করতে পারেন :
lensTransform lens transformFunc target =
current = view lens target
new = transformFunc current
set lens new target
এটি একটি ফাংশন নেয় এবং এটিকে একটি জটিল তথ্য কাঠামোর উপর "আপডেটেটার" রূপান্তর করে, কেবলমাত্র দর্শনে ফাংশনটি প্রয়োগ করে এবং এটি একটি নতুন ভিউ নির্মাণের জন্য ব্যবহার করে। সুতরাং 14 তম বহুভুজের তৃতীয় বিন্দুটি 10 টি পিক্সেলের দিকে সরানোর দৃশ্যে ফিরে যাওয়া, এটি এর lensTransform
মতো প্রকাশ করা যেতে পারে :
lens = scenePointLens 14 3
moveRightTen point = movePoint 10 0 point
newScene = lensTransform lens moveRightTen currentScene
এবং আপনাকে কেবল পুরো দৃশ্যটি আপডেট করতে হবে। এটি একটি খুব শক্তিশালী ধারণা এবং যখন আপনার যত্ন নেওয়া আপনার ডেটার অংশগুলি দেখার জন্য লেন্স তৈরির জন্য কিছু সুন্দর ফাংশন থাকে তখন এটি খুব ভাল কাজ করে works
তবে এটি বর্তমানে কার্যকরী প্রোগ্রামিং সম্প্রদায়ের মধ্যে খুব সুন্দর জিনিস রয়েছে। লেন্স দিয়ে কাজ করার জন্য ভাল গ্রন্থাগার সমর্থন পাওয়া মুশকিল, এবং তারা কীভাবে কাজ করে এবং আপনার সহকর্মীদের কী কী সুবিধা রয়েছে তা ব্যাখ্যা করা আরও বেশি কঠিন। লবণ একটি দানা সঙ্গে এই পদ্ধতির গ্রহণ করুন।