Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The focus (or via) path operator #24

Open
stanch opened this issue Feb 16, 2016 · 5 comments
Open

The focus (or via) path operator #24

stanch opened this issue Feb 16, 2016 · 5 comments

Comments

@stanch
Copy link
Contributor

stanch commented Feb 16, 2016

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?

@adamw
Copy link
Member

adamw commented Feb 17, 2016

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?

@stanch
Copy link
Contributor Author

stanch commented Feb 17, 2016

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.

@adamw
Copy link
Member

adamw commented Feb 17, 2016

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?

@stanch
Copy link
Contributor Author

stanch commented Feb 17, 2016

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.

@adamw
Copy link
Member

adamw commented Feb 18, 2016

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants