Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
data class Lens<S, A>(val get: (S) -> A, val set: (A, S) -> S)
fun <A, B, C> Lens<A, B>.compose(that: Lens<C, A>): Lens<C, B> =
Lens({ this.get(that.get(it)) }, { c, a -> that.set(this.set(c, that.get(a)), a) })
fun <A, B> Lens<A, B>.traverse(): Lens<List<A>, List<B>> =
Lens({ it.map { get(it) } }, { bs, aas -> bs.zip(aas).map { this.set(it.first, it.second) } })
object Play {
data class Point(val x: Double, val y: Double) {
companion object {
val x = Lens<Point, Double>({ it.x }, { x, p -> Point(x, p.y) })
}
}
data class Circle(val p: Point, val r: Double) {
companion object {
val p = Lens<Circle, Point>({ it.p }, { p, c -> Circle(p, c.r) })
}
}
data class Surface(val ps: List<Point>) {
companion object {
val ps = Lens<Surface, List<Point>>({ it.ps }, { ps, s -> Surface(ps) })
}
}
val x: Lens<Circle, Double> = Point.x.compose(Circle.p)
val y: Lens<Surface, List<Double>> = Point.x.traverse().compose(Surface.ps)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment