quicklens icon indicating copy to clipboard operation
quicklens copied to clipboard

The `focus` (or `via`) path operator

Open stanch opened this issue 9 years ago • 5 comments

This would allow supporting arbitrary lens.

trait Lens[A, B] {
  def modify(a: A, f: B => B): A
}

object EnglishVovels extends Lens[String, Char] {
  def modify(string: String, f: Char => Char) = string map {
    case v @ ('A' | 'E' | 'I' | 'O' | 'U' | 'a' | 'e' | 'i' | 'o' | 'u') => f(v)
    case x => x
  }
}

person.modify(_.name.focus(EnglishVovels)).using(_.toUpperCase)

What do you think?

stanch avatar Feb 16 '16 15:02 stanch

It's not immediately clear to me how that would work (sorry for being slow :) ) - what would be an example result and what would be the signature of focus?

adamw avatar Feb 17 '16 15:02 adamw

It would work exactly like each or at. In fact they can be rewritten as focus(Each) and Focus(At(3)) respectively, but I don’t think this is a good idea. The signature will be:

implicit class QuicklensFocus[A](val a: A) extends AnyVal {
  @compileTimeOnly
  def focus[B](lens: Lens[A, B]): B = sys.error("")
}

Expanded example:

val person = Person(
  name = "john",
  address = Address(
    street = "green street"
  )
)

val modified = person
  .modifyAll(_.name.focus(EnglishVovels), _.address.street.focus(EnglishVovels))
  .using(_.toUpperCase)

modified shouldEqual Person(
  name = "jOhn",
  address = Address(
    street = "grEEn strEEt"
  )
)

Not seen here, but you can continue traversing the path after a call to focus, just like with each.

stanch avatar Feb 17 '16 15:02 stanch

Thanks! So this would be kind of filtering the "collection" on which focus is called + mapping to some value, which can be then traversed further, correct?

adamw avatar Feb 17 '16 16:02 adamw

Yes, the idea is to be able to pass an arbitrary lens to focus. Another example is creating a lens that somehow modifies the scheme in a java.net.URI, even though it’s not a case class.

stanch avatar Feb 17 '16 18:02 stanch

This sounds good! Just would need good docs - or rather examples. The two examples (with person and URI) would be great to have in the docs

adamw avatar Feb 18 '16 07:02 adamw