ตลกดีที่ไม่มีใครเพิ่มเลนส์เพราะมันถูกสร้างมาเพื่อของแบบนี้ ดังนั้นนี่คือกระดาษพื้นหลัง CS ด้านบนนี่คือบล็อกที่สัมผัสสั้น ๆ เกี่ยวกับเลนส์ที่ใช้ใน Scala นี่คือการใช้งานเลนส์สำหรับ Scalaz และนี่คือรหัสบางส่วนที่ใช้ซึ่งดูเหมือนคำถามของคุณอย่างน่าประหลาดใจ และเพื่อลดแผ่นหม้อต้มนี่คือปลั๊กอินที่สร้างเลนส์ Scalaz สำหรับคลาสเคส
สำหรับคะแนนโบนัสนี่คือคำถามอื่น ๆ ที่เกี่ยวข้องกับเลนส์และกระดาษของ Tony Morris
เรื่องใหญ่เกี่ยวกับเลนส์คือสามารถประกอบได้ ดังนั้นพวกเขาจึงค่อนข้างยุ่งยากในตอนแรก แต่พวกเขาก็ยังคงได้รับประโยชน์ยิ่งคุณใช้มันมากขึ้น นอกจากนี้ยังเหมาะสำหรับการทดสอบเนื่องจากคุณต้องทดสอบเลนส์แต่ละชิ้นเท่านั้นและสามารถพิจารณาองค์ประกอบได้
ดังนั้นจากการใช้งานที่ให้ไว้ในตอนท้ายของคำตอบนี้คุณจะใช้เลนส์ได้อย่างไร ขั้นแรกประกาศเลนส์เพื่อเปลี่ยนรหัสไปรษณีย์ในที่อยู่และที่อยู่ในตัวบุคคล:
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
สุดท้ายใช้เลนส์นั้นเพื่อเปลี่ยน raj:
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)
นี่คือการใช้งานง่าย ๆ ซึ่งนำมาจาก Scalaz ซึ่งใช้สำหรับตัวอย่างนี้:
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
}