Skip to content

Instantly share code, notes, and snippets.

@tonymorris
Forked from retronym/lensed.scala
Created July 18, 2011 22:03
Show Gist options
  • Save tonymorris/1090787 to your computer and use it in GitHub Desktop.
Save tonymorris/1090787 to your computer and use it in GitHub Desktop.
Lensed
// see https://github.com/gseitz/Lensed
case class CoState[A, B](put: A => B, pos: A)
object CoState {
type Store[A, B] = CoState[A, B]
}
// fused get/set
case class Lens[A, B](lens: A => CoState[B, A]) {
def get(a: A): B = lens(a).pos
def set(a: A): B => A = lens(a).put
}
object Lensed {
import scalaz._
import Scalaz._
case class Address(street: String)
case class Person(name: String, address: Address)
object Person {
// currently generated
val name: Lens[Person, String] = Lens(_.name, (p, n) => p.copy(name = n))
val address: Lens[Person, Address] = Lens(_.address, (p, a) => p.copy(address = a))
// proposed
class PimpedLens[A](l: Lens[A, Person]) {
val name: Lens[A, String] = l andThen Person.name
val address: Lens[A, Address] = l andThen Person.address
}
implicit def pimpLens[A](l: Lens[A, Person]) = new PimpedLens(l)
}
object Address {
// Generated
val street: Lens[Address, String] = Lens(_.street, (p, s) => p.copy(street = s))
// proposed
class PimpedLens[A](l: Lens[A, Address]) {
val street: Lens[A, String] = l andThen Address.street
}
implicit def pimpLens[A](l: Lens[A, Address]) = new PimpedLens(l)
}
val p = Person("Brent", Address("Main St"))
Person.address.street.set(p, "Lower Main St")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment