Skip to content

Commit f427ec9

Browse files
EugeneFlesselleodersky
authored andcommitted
Do filter runtime operation based on a term level predicate
1 parent 57b17ac commit f427ec9

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

library/src/scala/Tuple.scala

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,10 @@ sealed trait Tuple extends Product:
9090
inline def reverseOnto[This >: this.type <: Tuple, Acc <: Tuple](acc: Acc): ReverseOnto[This, Acc] =
9191
(this.reverse ++ acc).asInstanceOf[ReverseOnto[This, Acc]]
9292

93-
/** A tuple consisting of all elements of this tuple that have types
94-
* for which the given type level predicate `P` reduces to the literal
95-
* constant `true`.
96-
*/
97-
inline def filter[This >: this.type <: Tuple, P[_ <: Union[This]] <: Boolean]: Filter[This, P] =
98-
val toInclude = constValueTuple[IndicesWhere[This, P]].toArray
99-
val arr = new Array[Object](toInclude.length)
100-
for i <- 0 until toInclude.length do
101-
arr(i) = this.productElement(toInclude(i).asInstanceOf[Int]).asInstanceOf[Object]
93+
/** A tuple consisting of all elements of this tuple that satisfy the predicate `p`. */
94+
inline def filter[This >: this.type <: Tuple, P[_ <: Union[This]] <: Boolean]
95+
(p: (x: Union[This]) => P[x.type]): Filter[This, P] =
96+
val arr = this.toArray.filter(x => p(x.asInstanceOf[Union[This]]))
10297
Tuple.fromArray(arr).asInstanceOf[Filter[This, P]]
10398

10499
object Tuple:

tests/pos/named-tuples-strawman-2.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ object TupleOps:
6060
case EmptyTuple => X
6161

6262
inline def concatDistinct[X <: Tuple, Y <: Tuple](xs: X, ys: Y): ConcatDistinct[X, Y] =
63-
(xs ++ ys.filter[Y, [Elem] =>> ![Contains[X, Elem]]]).asInstanceOf[ConcatDistinct[X, Y]]
63+
// Note the type parameter is needed due to the invariance of compiletime.ops.boolean.!
64+
extension [B <: Boolean](self: B) def negated: ![B] = (!self).asInstanceOf
65+
val ysDistinct = ys.filter[Y, [y] =>> ![Contains[X, y]]](xs.contains(_).negated)
66+
(xs ++ ysDistinct).asInstanceOf[ConcatDistinct[X, Y]]
6467

6568
object NamedTupleDecomposition:
6669
import NamedTupleOps.*

0 commit comments

Comments
 (0)