ट्रैक
/
Roc
Roc
/
अभ्यास
/
लेंस व्यक्ति
लेंस व्यक्ति

लेंस व्यक्ति

मध्यम

निर्देश

नेस्टेड रिकॉर्ड अपडेट करने के लिए लेंस का इस्तेमाल कीजिए (यह उन भाषाओं पर लागू है जिनमें इम्यूटेबल डेटा होता है)।

नेस्टेड और इम्यूटेबल रिकॉर्ड के फील्ड अपडेट करना थोड़ा परेशान करने वाला होता है। ऐसे मामलों में संरचना जितनी गहरी होती है, कोड उतना ही बोझिल होता है। मान लीजिए, आपके पास एक Person है, जिसमें एक Address है, जिसमें एक Street है, जिसमें एक Number है। अब Number को अपडेट करने के लिए नए Number वाली नई Street बनानी पड़ती है, फिर नई Street वाला नया Address, और अंत में नए Address वाला नया Person बनाना पड़ता है। क्या आप पहले ही उलझ गए हैं?

इस समस्या को हल करने का एक तरीका है लेंस का इस्तेमाल करना।

लेंस का इस्तेमाल करके रिकॉर्ड एक्सेस करने वाले कई फंक्शन बनाइए। टेस्ट सूट भी आपको लेंस के बिना काम करने देता है, ताकि आप अलग-अलग तरीके आज़मा सकें।

Roc में लेंस का इस्तेमाल ज़्यादा नहीं होता, क्योंकि रिकॉर्ड अपडेट सिंटैक्स ज़्यादातर मामलों में बखूबी काम कर देता है। उदाहरण के लिए, इस नेस्टेड रिकॉर्ड को देखिए:

bob = { hair: { color: Brown, length: Long }, mouth: Smiling, height: 6.0 }

अब चलिए बॉब के बाल काटते हैं:

new_bob = { ..bob, hair: { ..bob.hair, length: Short } }

किसी लेंस की ज़रूरत ही नहीं! फिर भी, Roc में लेंस कम इस्तेमाल होते हैं, जबकि Haskell और Scala जैसी भाषाओं में ये आम हैं। इसलिए आपके मन में यह जिज्ञासा हो सकती है कि Roc में इन्हें कैसे बनाया जाए। यह Roc के कुछ एडवांस्ड फीचर का अभ्यास करने का भी अच्छा तरीका है, जैसे पैरामीटराइज़्ड टाइप और फंक्शन रखने वाले रिकॉर्ड। तो Roc में लेंस दर्शाने का एक तरीका यह है:

Lens(whole, part) := {
	get : whole -> part,
	set : whole, part -> whole,
}

यह एक पैरामीटराइज़्ड टाइप है, जिसमें whole और part किसी भी टाइप के हो सकते हैं। आम तौर पर whole एक रिकॉर्ड होता है, जबकि part किसी भी फील्ड टाइप का हो सकता है। get फील्ड में एक फंक्शन रखा जाता है, जो दिए गए whole का कोई खास part लौटाता है। वहीं set फील्ड में एक फंक्शन रखा जाता है, जो दिए गए whole की एक कॉपी लौटाता है, जिसमें बस एक खास part को दिए गए part से बदल दिया गया होता है।

उदाहरण के लिए, किसी व्यक्ति के बाल पाने या बदलने वाला लेंस यह है:

hair_lens = {
	get: |person| person.hair,
	set: |person, hair| { ..person, hair },
}

इस लेंस से हम बॉब के बालों पर ध्यान केंद्रित कर सकते हैं, ऐसे:

bob_hair = bob |> hair_lens.get

और हम उसके बाल इस तरह बदल सकते हैं:

new_hair = { ..bob.hair, length: Short }
new_bob = bob |> (hair_lens.set)(new_hair)

ध्यान दीजिए: hair_lens.set के चारों ओर लगे गोल ब्रैकेट ज़रूरी हैं। इनके बिना Roc hair_lens के टाइप में set नाम का फंक्शन ढूँढने लगेगा।

लेंस तब खास तौर से काम आते हैं जब आप इन्हें आपस में जोड़ना शुरू करते हैं, क्योंकि इससे आप गहराई तक नेस्टेड हिस्से पा और बदल सकते हैं। यह काम ऐसा फंक्शन बनाकर किया जा सकता है:

compose : Lens(outer, inner), Lens(inner, part) -> Lens(outer, part)

यह फंक्शन बन जाने के बाद, आप इससे बालों की लंबाई वाला लेंस इस तरह बना सकते हैं:

length_lens = {
	get: |hair| hair.length,
	set: |hair, length| { ..hair, length },
}
hair_length_lens = compose(hair_lens, length_lens)

अब आप बॉब के बाल एक बार फिर काट सकते हैं:

set_hair_length = hair_length_lens.set
new_bob = bob |> set_hair_length(Short)

आप ऐसा फंक्शन भी बनाना चाह सकते हैं, जिससे किसी नेस्टेड हिस्से पर कोई भी बदलाव लागू किया जा सके:

over : Lens(whole, part), whole, (part -> part) -> whole

यह बन जाने के बाद, आप over का इस्तेमाल इस तरह कर सकते हैं:

cut_hair = |current_length| match current_length {
	Long => Short
	Short => Bald
	Bald => Bald
}
new_bob = hair_length_lens |> over(bob, cut_hair)

इस अभ्यास में, टेस्ट यह जाँचेंगे कि आपका कोड नीचे दिए गए नेस्टेड रिकॉर्ड के अलग-अलग नेस्टेड हिस्सों को बदल पाता है या नहीं:

test_person : Person
test_person = {
	name: { forenames: "Jane Joanna", surname: "Doe" },
	birth: {
		born_at: { street: "Longway", house_number: 1024, place: "Springfield", country: "United States" },
		born_on: { year: 1984, month: 4, day: 12 },
	},
	address: { street: "Shortlane", house_number: 2, place: "Fallmeadow", country: "Canada" },
}

हमारा सुझाव है कि पहले आप Roc के रिकॉर्ड अपडेट सिंटैक्स से टेस्ट पास कीजिए, और फिर उसकी जगह लेंस इस्तेमाल करके देखिए।

GitHub के ज़रिए संपादित करें यह लिंक एक नई विंडो या टैब में खुलता है
Roc Exercism

लेंस व्यक्ति शुरू करने के लिए तैयार हैं?

Exercism पर साइन अप कीजिए और Roc को 125 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।