Quicklens is a small library which allows to modify deeply nested fields in case classes e.g.:
modify(person)(_.address.street.name).using(_.toUpperCase), without the need to create dedicated lens objects.
I got some very good feedback on the initial release – thanks! There’s also a spin-off implementation, using a different syntax.
One problem that I anticipated from the beginning and also mentioned in the comments, was that it wasn’t possible to traverse
Optional fields. And that’s of now fixed!
Lists can be “unwrapped” using the
.each method. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13
import com.softwaremill.quicklens._ case class Street(name: String) case class Address(street: Option[Street]) case class Person(addresses: List[Address]) val person = Person(List( Address(Some(Street("1 Functional Rd."))), Address(Some(Street("2 Imperative Dr."))) )) val newPerson = modify(person)(_.addresses.each.street.each.name) .using(_.toUpperCase)
.each can only be used inside
modify. You can add support for your own containers by providing an implicit
QuicklensFunctor[C] with the appropriate
C type parameter (there are default implementations for
- added documentation on how to create lenses, that is a modification of a path parametrized by the actual object:
val nameLens = modify(_: Person)(_.address.street.name). This can be later used as follows:
- a dedicated method to set a new value of a field, instead of transforming the old value:
modify(person)(_.address.street.name).setTo("2 Imperative Dr.")
andThenModifymethod provided by an implicit conversion to combine two lenses:
1 2 3 4 5
val modifyAddress = modify(_: Person)(_.address) val modifyStreetName = modify(_: Address)(_.street.name) val newPerson = (modifyAddress andThenModify modifyStreetName)(person) .using(_.toUpperCase)
There were also some comments that the current syntax suggests mutable behaviour (which, of course, is not true – all modifications result in copies of the case classes to be created). An alternative could be:
However it is a bit longer than the original. What do you think?
Quicklens is available on GitHub under the Apache2 license.