मजेदार है कि किसी ने लेंस नहीं जोड़ा, क्योंकि वे इस तरह के सामान के लिए MADE थे। तो, यहाँ एक CS बैकग्राउंड पेपर है, यहाँ एक ब्लॉग है, जो स्कैला में लेंस के उपयोग पर संक्षिप्त रूप से स्पर्श करता है, यहाँ Scalaz के लिए एक लेंस कार्यान्वयन है और यहाँ कुछ कोड का उपयोग किया गया है, जो आश्चर्यजनक रूप से आपके प्रश्न की तरह दिखता है। और, बॉयलर प्लेट पर कटौती करने के लिए, यहां एक प्लगइन है जो केस क्लासेस के लिए स्केलाज़ लेंस उत्पन्न करता है।
बोनस अंक के लिए, यहां एक और SO प्रश्न है जो लेंस पर स्पर्श करता है, और टोनी मॉरिस द्वारा एक पेपर ।
लेंस के बारे में बड़ी बात यह है कि वे रचना योग्य हैं। इसलिए वे पहली बार में थोड़े बोझिल होते हैं, लेकिन वे जितना अधिक आप उनका उपयोग करते हैं, उतना जमीन हासिल करते रहते हैं। इसके अलावा, वे परीक्षण क्षमता के लिए महान हैं, क्योंकि आपको केवल व्यक्तिगत लेंस का परीक्षण करने की आवश्यकता है, और उनकी संरचना के लिए अनुमति दे सकते हैं।
इसलिए, इस उत्तर के अंत में दिए गए कार्यान्वयन के आधार पर, यहां बताया गया है कि आप इसे लेंस के साथ कैसे करेंगे। सबसे पहले, एक पते में एक ज़िप कोड और एक व्यक्ति में एक पता बदलने के लिए लेंस घोषित करें:
val addressZipCodeLens = Lens(
get = (_: Address).zipCode,
set = (addr: Address, zipCode: Int) => addr.copy(zipCode = zipCode))
val personAddressLens = Lens(
get = (_: Person).address,
set = (p: Person, addr: Address) => p.copy(address = addr))
अब, उन्हें एक लेंस प्राप्त करने के लिए लिखें जो एक व्यक्ति में ज़िपकोड को बदलता है:
val personZipCodeLens = personAddressLens andThen addressZipCodeLens
अंत में, राज बदलने के लिए उस लेंस का उपयोग करें:
val updatedRaj = personZipCodeLens.set(raj, personZipCodeLens.get(raj) + 1)
या, कुछ सिंथेटिक चीनी का उपयोग कर:
val updatedRaj = personZipCodeLens.set(raj, personZipCodeLens(raj) + 1)
या और भी:
val updatedRaj = personZipCodeLens.mod(raj, zip => zip + 1)
इस उदाहरण के लिए उपयोग किया गया सरल कार्यान्वयन, स्कैलाज़ से लिया गया है:
case class Lens[A,B](get: A => B, set: (A,B) => A) extends Function1[A,B] with Immutable {
def apply(whole: A): B = get(whole)
def updated(whole: A, part: B): A = set(whole, part) // like on immutable maps
def mod(a: A, f: B => B) = set(a, f(this(a)))
def compose[C](that: Lens[C,A]) = Lens[C,B](
c => this(that(c)),
(c, b) => that.mod(c, set(_, b))
)
def andThen[C](that: Lens[B,C]) = that compose this
}