Skip to content

Instantly share code, notes, and snippets.

@holoed
Created September 13, 2015 19:27
Show Gist options
  • Select an option

  • Save holoed/4c8ffa719fef4298bef2 to your computer and use it in GitHub Desktop.

Select an option

Save holoed/4c8ffa719fef4298bef2 to your computer and use it in GitHub Desktop.
Scala Lenses
/**
* Created by epentangelo on 27/08/2015.
*/
object Lenses {
type Lens [a, b] = (a => b, a => b => a)
def makeLens[a, b](get: a => b, set: a => b => a) : Lens[a, b] = (get, set)
def get[a, b] (lens: Lens[a, b]) (obj: a) : b = lens._1(obj)
def set[a, b] (lens: Lens[a, b]) (obj: a) (v:b) : a = lens._2(obj)(v)
def compose[a, b, c] (x: Lens[a,b]) (y: Lens[b, c]) : Lens[a, c] =
makeLens[a, c](obj => get (y) (get(x)(obj)), obj => v => set (x) (obj) (set (y) (get (x)(obj)) (v)))
}
case class Person(firstName: String, lastName: String) {
override def toString() = "(firstName: " + firstName.toString() + " lastName: " + lastName.toString() + ")"
}
case class Family(husband: Person, wife: Person) {
override def toString() = "(husband: " + husband.toString() + " wife: " + wife.toString() + ")"
}
object Main {
def main (args: Array[String]) {
val husband = Person("Homer", "Simpson")
val wife = Person("Marge", "Simpson")
val family = Family(husband, wife)
println(family)
val wifeLens : Lenses.Lens[Person, String] =
Lenses.makeLens[Person, String] ({ case Person(firstName, _) => firstName },
{ case Person(_, lastName) => (v:String) => Person(v, lastName) })
val familyLens : Lenses.Lens[Family, Person] =
Lenses.makeLens[Family, Person] ({ case Family (wife, _) => wife},
{ case Family (_, husband) => (v: Person) => Family(husband, v)})
// println (Lenses.get[Person, String] (wifeLens) (wife))
// println (Lenses.get[Family, Person](familyLens) (family))
val composedLens: Lenses.Lens[Family, String] = Lenses.compose (familyLens) (wifeLens)
println (Lenses.set (composedLens) (family) ("Margareth"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment