Lens library in less than 40-lines of Scala:
import com.github.pathikrit.sauron._
case class Person(address: Address)
case class Address(street: Street)
case class Street(name: String)
val person = Person(Address(Street("1 Functional Rd.")))
lens(person)(_.address.street.name)(_.toUpperCase)
There is zero overhead. The lens
macro simply expands to this during compilation:
person.copy(address = person.address.copy(
street = person.address.street.copy(
name = (person.address.street.name).toUpperCase)
)
)
Reusable lenses:
val f1 = lens(person)(_.address.street.name)
val p1: Person = f1(_.toLowerCase)
val p2: Person = f1(_.toUpperCase)
The above lens only updates a particular person. You can make even more generic lenses that can update any Person
:
val f = lens(_: Person)(_.address.street.name)
val p3: Person = f(p1)(_.toUpperCase)
val p4: Person = f(p2)(_.toLowerCase)
Consult the tests for more examples.
Usage: In your build.sbt
, add the following entries:
resolvers += Resolver.bintrayRepo("pathikrit", "maven")
libraryDependencies += "com.github.pathikrit" %% "sauron" % "0.2.0"
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0-M5" cross CrossVersion.full)
Note: Significant changes were introduced in v0.2. v0.1 used to have an interesting recursive macro
The latest published versions can be found here: http://dl.bintray.com/pathikrit/maven/com/github/pathikrit
For advanced operations like lens composition etc, please consider a library like Monocole. This library is inspired by the excellent work done by @adamw in his quickLens library.