Skip to content

Latest commit

 

History

History
93 lines (71 loc) · 3.88 KB

Optics.MD

File metadata and controls

93 lines (71 loc) · 3.88 KB

Optics

  • Putting Lenses to Work - John Wiegley (video) slides (blog post)
  • Taking Updates Seriously - Danel Ahman, Tarmo Uustalu (paper)
  • (Haskell) Optics in Haskell - Functional Tricity #13 - Paweł Sączawa (video)

Iso

  • Beyond Scala Lenses - Julien Truffaut: (video)

Prism

  • Beyond Scala Lenses - Julien Truffaut: (video)

Lens

Van Laarhoven Optics

Profunctor Optics

Optics (Iso, Lens, Prism, etc) can be implemented using different Profunctors. If we have following Profunctor hierarchy:

trait Strong[P[_, _]] extends Profunctor[P] {
  def first[A,B,C](pab: P[A, B]): P[(A, C), (B, C)]
}

trait Choice[P[_, _]] extends Profunctor[P] {
  def left[A,B,C](pab: P[A, B]):  P[Either[A, C], Either[B, C]]
  def right[A,B,C](pab: P[A, B]): P[Either[C, A], Either[C, B]] = dimap(_.swap, _.swap)(left(pab))
}

trait Step[P[_,_]] extends Choice[P] with Strong[P] {
  def step[A,B,C,D](pab: P[A,B]): P[Either[D, (A,C)], Either[D, (B,C)]] = right(first(pab))
}

trait Walk[P[_,_]] extends Step[P] {
  def walk[A,B,F[_]](pab: P[A,B])(implicit FT: Traverse[F]): P[F[A], F[B]]
}

trait Settable[P[_,_]] extends Walk[P] {
  def mapping[A,B,F[_]](pab: P[A,B])(implicit FT: Functor[F]): P[A,B] => P[F[A], F[B]]
}

trait Closed[P[_,_]] extends Profunctor[P] {
  def closed[A,B,X](pab: P[A,B]): P[X=>A, X=>B]
}

Then optics can be expressed in following way:

trait Iso[S, T, A, B] {
  def run[P[_, _]](pab: P[A, B])(implicit P: Profunctor[P]): P[S, T]
}

trait Lens[S, T, A, B] {
  def run[P[_, _]](pab: P[A, B])(implicit S: Strong[P]): P[S, T]
}

trait Prism[S, T, A, B] {
  def run[P[_, _]](pab: P[A, B])(implicit C: Choice[P]): P[S, T]
}

trait AffineTraversal[S, T, A, B] {
  def run[P[_, _]](pab: P[A, B])(implicit S: Step[P]): P[S, T]
}

trait Traversal[S, T, A, B] {
  def run[P[_, _]](pab: P[A, B])(implicit W: Walk[P]): P[S, T]
}

trait SEC[S, T, A, B] {
  def run[P[_, _]](pab: P[A, B])(implicit S: Settable[P]): P[S, T]
}

trait Grates[S, T, A, B] { // https://r6research.livejournal.com/28050.html
  def run[P[_,_]](pab: P[A, B])(implicit C: Closed[P]): P[S, T]
}
  • Resources:
    • Bartosz Milewski - Profunctor Optics: The Categorical Approach (video)
    • Mainline Profunctor Heirarchy for Optics (blog post)
    • Jeremy Gibbons - Profunctor Optics Modular Data Accessors (video)
    • Grate: A new kind of Optic: (blog post)
    • Tambara Modules - Brendan Fong (video)
    • Profunctor optics, a categorical update - Mario Román, Bryce Clarke, Fosco Loregian, Emily Pillmore, Derek Elkins, Bartosz Milewski (video), (slides), (gist)