Open julien-truffaut opened 3 years ago
IMO, filter
and filterIndex
should return the same optic types. For example for List
filter (predicate: A => Boolean): Traversal[List[A], A]
filterIndex(predicate: Int => Boolean): Traversal[List[A], A]
One way to get this is to rename the current filter
method to select
https://github.com/optics-dev/Monocle/blob/master/core/shared/src/main/scala/monocle/Lens.scala#L335-L336 and implement filter
in terms of each
and select
select(predicate: A => Boolean): Optional[List[A], List[A]]
filter(predicate: A => Boolean): Traversal[List[A], A] =
each andThen select(predicate)
IMHO:
Seq => (A=> Boolean) => Option[A]
is called find
in the Scala libraryYeah I completely agree, filter
and filterIndex
should return a Traversal
.
find
is a great name but we already have a method find
on Fold
and Traversal
to fetch the first target that matches the predicate https://github.com/optics-dev/Monocle/blob/master/core/shared/src/main/scala/monocle/Traversal.scala#L50-L51
Maybe a real use case would help us to find a good name. I will try to find one tomorrow.
case class User(name: String, country: String, coins: Int)
val eda = User("Eda", "Germany", 5)
val bob = User("Bob", "UK", 2)
val incrementUKUser = Optional.foo[User](_.country == "UK").andThen(Focus[User](_.coins)).modify(_ + 10)
incrementUKUser(eda) // do nothing
// res: User = User("Eda", "Germany", 5)
incrementUKUser(bob)
// res: User = User("Bob", "UK", 12)
I am not sure how should we call foo
.
Possibly first
?
@yilinwei there is already a first
method on some optics, though I am not sure it is very useful
https://github.com/optics-dev/Monocle/blob/master/core/shared/src/main/scala/monocle/Lens.scala#L77
I think those look like generic Profunctor
method which isn't too useful while you're dealing with a concrete optic.
What about filter1
and filterIndex1
, or something closer to the stdlib like findFirst
?
filter(predicate: A => Boolean): Traversal[List[A], A] =
each andThen select(predicate)
filter
doesn't work well with type inference. Scala cannot figure out the expected type of predicate
. We have a similar problem with filterIndex((key: Int) => key > 5)
, we need to annotate key
.
That's why I think we should offer:
def foo(predicate: A => Boolean): Optional[A, A] =
Optional[A, A](
value => if (predicate(value)) Some(value) else None)(
newValue => current => if (predicate(current)) newValue else current
)
foo
is currently called filter
which in my opinion is confusing.
filter
andfilterIndex
are two optic combinators with similar name and behaviour but different types, which may be confusing.It may be easier to see the confusion when we check the type of
filter
andfilterIndex
forList