Skip to content

Instantly share code, notes, and snippets.

@igstan
Last active August 29, 2015 14:13
Show Gist options
  • Save igstan/a3781b52dbf7092ab15e to your computer and use it in GitHub Desktop.
Save igstan/a3781b52dbf7092ab15e to your computer and use it in GitHub Desktop.
Simple lenses in Scala.
object Lenses {
// Main API
case class Lens[A, B](get: A => B, set: (A, B) => A) {
def compose[C](other: Lens[B, C]): Lens[A, C] = {
Lens[A, C](
get = (a: A) => other.get(get(a)),
set = (a: A, c: C) => set(a, other.set(get(a), c))
)
}
}
// Example structures
case class Address(street: String)
case class Person(name: String, address: Address)
// Lenses for above structures
object Address {
val street: Lens[Address, String] = Lens(
get = (a) => a.street,
set = (a,s) => a.copy(street = s)
)
}
object Person {
val name: Lens[Person, String] = Lens(
get = (p) => p.name,
set = (p,n) => p.copy(name = n)
)
val address: Lens[Person, Address] = Lens(
get = (p) => p.address,
set = (p,a) => p.copy(address = a)
)
}
// Usage
def example(): Unit = {
val personStreet = Person.address compose Address.street
val john = Person("John", Address("Șelari"))
println(personStreet.get(john))
println(personStreet.set(john, "Smârdan"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment