Skip to content

Instantly share code, notes, and snippets.

@chrislewis
Created February 16, 2012 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrislewis/1845535 to your computer and use it in GitHub Desktop.
Save chrislewis/1845535 to your computer and use it in GitHub Desktop.
class Lens[A, B](
val get: A => B,
val set: (B, A) => A
) {
def andThen[C](l: Lens[B, C]): Lens[A, C] =
Lens(
(a) => l.get(get(a)),
(c, a) => set(l.set(c, get(a)), a)
)
}
object Lens {
def apply[A, B](
gf: A => B,
sf: (B, A) => A
): Lens[A, B] = new Lens(gf, sf)
}
/* A simple model. */
case class Address(street: String, zip: String)
case class Person(name: String, address: Address)
/* A Lenses for the Address of a Person and the street of an Address. */
val paL = Lens[Person, Address](_.address, (a, p) => p.copy(address = a))
val asL = Lens[Address, String](_.street, (s, a) => a.copy(street = s))
/* Composition of the above eases access to a person.address.street. */
val pasL = paL andThen asL
val chris = Person("Chris", Address("201 B", "32080"))
pasL.get(chris)
pasL.set("67th", chris)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment