Skip to content

Instantly share code, notes, and snippets.

@gseitz
Created February 6, 2014 08:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gseitz/8840286 to your computer and use it in GitHub Desktop.
Save gseitz/8840286 to your computer and use it in GitHub Desktop.
Automatically derive a Traverse instance for "Generic Lenses"
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait GenLens[T[_]] {
def get[B](a: T[B]): B
def set[A, B](a: T[A], b: B): T[B]
}
implicit def lensTraversable[T[_]](implicit l: GenLens[T]): Traverse[T] = new Traverse[T] {
def traverseImpl[G[_], A, B](fa: T[A])(f: (A) => G[B])(implicit G: Applicative[G]) = {
G.map(f(l.get[A](fa)))(l.set[A, B](fa, _))
}
}
case class Bar[A](a: A, b: Int, c: Int)
implicit def barLens: GenLens[Bar] = new GenLens[Bar] {
def set[A, B](a: Bar[A], b: B) = a.copy(a = b)
def get[B](a: Bar[B]) = a.a
}
// Exiting paste mode, now interpreting.
warning: there were 3 feature warning(s); re-run with -feature for details
defined trait GenLens
lensTraversable: [T[_]](implicit l: GenLens[T])scalaz.Traverse[T]
defined class Bar
barLens: GenLens[Bar]
scala> Traverse[Bar].sequenceU(Bar(List("foo"), 1,2))
res8: List[Bar[String]] = List(Bar(foo,1,2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment