-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Proposal
Define a globally available infix
method in(collection)
for all types, enabling the following:
5 in Seq(1,5,3) // true
"cba" in "abc".permutations // true
'e' in "hello" // true
3 in (1 to 10) // true
1) Intuitive phrasing
There are many scenarios where asking whether an element is in
a collection reads more intuitively than asking if a collection .contains
an element.
if thing in Seq(............) then
vs
if Seq(............).contains(thing)
2) Generalizing membership checking, performantly.
Some collections kinds don't have a .contains
method, like Iterator
, where you would instead need to do .exists(_ == thing)
to achieve the same meaning.
So, in
could serve to generalize this operation -- sometimes working as an alias to .contains
, and other times as an alias to .exists
, while the high-level meaning is the same regardless so programmers don't need to think about this implementation detail. If you later change the underlying collection type, these callsites won't be impacted.
Implementation
It's possible to implement this for all collections performantly, through typeclasses. A few people on the discord gave a workable implementation here.
trait Membership[Item, Coll]:
infix def in(col: Coll, item: Item): Boolean
object Membership:
given seq: [A, S[x] <: Seq[x]] => Membership[A, S[A]]:
override infix def in(seq: S[A], item: A): Boolean =
seq.contains(item)
given set: [A, S[x] <: Set[x]] => Membership[A, S[A]]:
override infix def in(set: S[A], item: A): Boolean =
set.contains(item)
given iterable: [A] => Membership[A, Iterable[A]]:
override def in(iter: Iterable[A], item: A): Boolean =
iter.exists(_ == item)
// ...
Another example of an implementation
extension [A](a: A)
def in[B >: A](col: Iterable[B]): Boolean =
col match
case seq: Seq[_] => seq.contains(a)
case set: Set[_] => set.contains(a)
case map: Map[_, _] => map.contains(a)
case iter => iter.exists(_ == a)
// ...
It would be great to see this as a builtin method in the stdlib, free of any manual import requirements.
Thanks.