Skip to content

Commit bc9dcbf

Browse files
Merge pull request #9235 from dotty-staging/filter-tuple
Add Filter type to Tuple
2 parents 50df4d2 + 33354df commit bc9dcbf

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ reference
1212
scala-days-2019-slides
1313
i7048e.scala
1414
i8052.scala
15+
tuple-filter.scala
1516

1617
# Stale symbol: package object scala
1718
seqtype-cycle

library/src/scala/Tuple.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,24 @@ object Tuple {
125125
case h *: t => Concat[F[h], FlatMap[t, F]]
126126
}
127127

128+
/** Filters out those members of the tuple for which the predicate `P` returns `false`.
129+
* A predicate `P[X]` is a type that can be either `true` or `false`. For example:
130+
* ```
131+
* type IsString[x] = x match {
132+
* case String => true
133+
* case _ => false
134+
* }
135+
* Filter[(1, "foo", 2, "bar"), IsString] =:= ("foo", "bar")
136+
* ```
137+
*/
138+
type Filter[Tup <: Tuple, P[_] <: Boolean] <: Tuple = Tup match {
139+
case EmptyTuple => EmptyTuple
140+
case h *: t => P[h] match {
141+
case true => h *: Filter[t, P]
142+
case false => Filter[t, P]
143+
}
144+
}
145+
128146
/** Given two tuples, `A1 *: ... *: An * At` and `B1 *: ... *: Bn *: Bt`
129147
* where at least one of `At` or `Bt` is `EmptyTuple` or `Tuple`,
130148
* returns the tuple type `(A1, B1) *: ... *: (An, Bn) *: Ct`

tests/neg/tuple-filter.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type P[x] <: Boolean = x match {
2+
case 3 => false
3+
case _ => true
4+
}
5+
type RejectAll[x] = false
6+
7+
def Test =
8+
summon[Tuple.Filter[(1, 2, 3, 4), P] =:= EmptyTuple] // error
9+
summon[Tuple.Filter[(1, 2, 3, 4), RejectAll] =:= (1, 2, 3)] // error
10+
summon[Tuple.Filter[EmptyTuple, P] =:= (1, 2, 3)] // error

tests/pos/tuple-filter.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type P[x] <: Boolean = x match {
2+
case 3 => false
3+
case _ => true
4+
}
5+
type RejectAll[x] = false
6+
7+
def Test =
8+
summon[Tuple.Filter[(1, 2, 3, 4), P] =:= (1, 2, 4)]
9+
summon[Tuple.Filter[(1, 2, 3, 4), RejectAll] =:= EmptyTuple]
10+
summon[Tuple.Filter[EmptyTuple, P] =:= EmptyTuple]

0 commit comments

Comments
 (0)