Güncelleme için daha temiz bir yol yapıları iç içe
**9 iki es şu var ki:
case class Address(street: String, city: String, state: String, zipCode: Int)
case class Person(firstName: String, lastName: String, address: Address)
ve Person
sınıf aşağıdaki örnek:
val raj = Person("Raj", "Shekhar", Address("M Gandhi Marg",
"Mumbai",
"Maharashtra",
411342))
Şimdi ise raj
zipCode
güncelleme istersem o zaman yaparım:
val updatedRaj = raj.copy(address = raj.address.copy(zipCode = raj.address.zipCode 1))
Bu iç içe daha fazla seviyeleri ile bu daha da çirkin olur. Böyle iç içe geçmiş yapıları güncelleştirmek için daha temiz bir yol (Clojure gibi bir şey update-in
) var mı?
CEVAP
Kimse bu tür şeyler için YAPILMIŞ beri lens eklendi, bu çok komik. Yani, here CS arka plan kağıt üzerinde, here bir blog olan dokunmatik kısaca lens kullanımı Scala, here bir lens uygulaması için Scalaz ve here bazı kodlar kullanarak, şaşırtıcı gibi görünüyor soru. Ve, kazan plaka, here's dava sınıflar için Scalaz lensler üreten bir eklenti kesmek için.
Bonus puan için, here's S. O. başka bir lens ve Tony Morris tarafından paper hangi dokunuşlar soru.
Lensler hakkında büyük bir anlaşma birleştirilebilir olmasıdır. İlk başta biraz hantal, ama daha onları kullanın zemin kazanmaya devam ediyorlar. Ayrıca, yalnızca tek bir lens test etmek gerek, ve hafife bileşimleri alabilir, test edilebilirlik için çok iyiler.
Yani, bir uygulama bu cevap sonunda verdiği bilgilere göre, burada lens ile bunu nasıl yaptığınızla ilgili. İlk olarak, objektif bir adres bir posta kodu değişikliği bildirmek için, ve bir kişi bir adres:
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))
Şimdi, bunları bir kişiye posta kodu değiştiren bir lens almak için Oluştur:
val personZipCodeLens = personAddressLens andThen addressZipCodeLens
Son olarak, bu lens raj değiştirmek için kullanın:
val updatedRaj = personZipCodeLens.set(raj, personZipCodeLens.get(raj) 1)
Ya da, bazı sözdizimsel şeker kullanarak:
val updatedRaj = personZipCodeLens.set(raj, personZipCodeLens(raj) 1)
Hatta:
val updatedRaj = personZipCodeLens.mod(raj, zip => zip 1)
İşte size basit bir uygulama, Scalaz, alınan bu örnek için kullanılır:
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
}
Daha temiz bir yaklaşım için pek çok &...
Nasıl daha sonra düz metin alma için e...
Nasıl div içeriğini daha büyük değil y...
Güncelleme ve silme için HTTP durum ko...
Toplu N günden daha eski dosyaları sil...