• Stars
    star
    168
  • Rank 216,869 (Top 5 %)
  • Language
    Scala
  • Created about 9 years ago
  • Updated about 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Yet another Scala lens macro

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.