Yet another Scala lens macro
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
project
src
.gitignore
README.md
build.sbt

README.md

Sauron Circle CI Download

Lightweight lens library in less than 50-lines of Scala:

case class Person(address: Address)
case class Address(street: Street)
case class Street(name: String)
val person = Person(Address(Street("1 Functional Rd.")))

import com.github.pathikrit.sauron._

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)
  )
)

Simple setters:

lens(person)(_.address.street.name).setTo("1 Objective Rd.")

Reusable lenses:

val f1 = lens(person)(_.address.street.name)

val p1: Person = f1(_.toLowerCase)
val p2: Person = f1(_.toUpperCase)

Lens factories: 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)

Lens composition:

val lens1: Person ~~> Address = lens(_: Person)(_.address)
val lens2: Address ~~> String = lens(_: Address)(_.street.name)

val lens3: Person ~~> String = lens1 andThenLens lens2 // or lens2 composeLens lens1
val p5: Person = lens3(person)(_.toLowerCase)

sbt: In your build.sbt, add the following entries:

resolvers += Resolver.bintrayRepo("pathikrit", "maven")

libraryDependencies += "com.github.pathikrit" %% "sauron" % "1.1.0"

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0-M5" cross CrossVersion.full)

This library is inspired by the clever work done by @adamw in his quicklens library.