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

Combine cases of Tuple.Zip disjoint from (h1 *: t1, h2 *: t2) #21287

Merged
merged 2 commits into from
Nov 18, 2024

Conversation

EugeneFlesselle
Copy link
Contributor

@EugeneFlesselle EugeneFlesselle commented Jul 29, 2024

If we reach the second case of Zip[T1 <: Tuple, T2 <: Tuple], then we know (T1, T2) is disjoint from (NonEmptyTuple, NonEmptyTuple), from which we can conclude at least one of the two is an EmptyTuple.

Addressing #19175

@EugeneFlesselle
Copy link
Contributor Author

EugeneFlesselle commented Jul 29, 2024

Well actually it looks like the doc was just incorrect:

/** Given two tuples, `A1 *: ... *: An * At` and `B1 *: ... *: Bn *: Bt`
* where at least one of `At` or `Bt` is `EmptyTuple` or `Tuple`,
* returns the tuple type `(A1, B1) *: ... *: (An, Bn) *: Ct`
* where `Ct` is `EmptyTuple` if `At` or `Bt` is `EmptyTuple`, otherwise `Ct` is `Tuple`.
*/
type Zip[T1 <: Tuple, T2 <: Tuple] <: Tuple = (T1, T2) match {
case (h1 *: t1, h2 *: t2) => (h1, h2) *: Zip[t1, t2]
case (EmptyTuple, _) => EmptyTuple
case (_, EmptyTuple) => EmptyTuple
}

-- [E007] Type Mismatch Error: tests/playground/example.scala:10:59 ------------
10 |  val z: Tuple.Zip[Int *: Int *: Tuple, String *: Tuple] = (1, "a") *: (??? : Tuple)
   |                                                           ^^^^^^^^^^^^^^^
   |Found:    (Int, String) *: Tuple
   |Required: (Int, String) *: Tuple.Zip[Int *: Tuple, Tuple]
   |
   |Note: a match type could not be fully reduced:
   |
   |  trying to reduce  Tuple.Zip[Int *: Tuple, Tuple]
   |  failed since selector (Int *: Tuple, Tuple)
   |  does not match  case (h1 *: t1, h2 *: t2) => (h1, h2) *: Tuple.Zip[t1, t2]
   |  and cannot be shown to be disjoint from it either.
   |  Therefore, reduction cannot advance to the remaining cases
   |
   |    case (EmptyTuple, _) => EmptyTuple
   |    case Any => Tuple

even though the doc would suggest the match type reduces to (Int, String) *: Tuple.

@EugeneFlesselle
Copy link
Contributor Author

EugeneFlesselle commented Jul 29, 2024

@sjrd do you concur with logic in the commit message of f8e584d, as I wouldn't mind confirmation.

@EugeneFlesselle EugeneFlesselle changed the title Drop Tuple.Zip unreachable match type case Combine cases of Tuple.Zip disjoint from (h1 *: t1, h2 *: t2) Jul 29, 2024
@EugeneFlesselle EugeneFlesselle enabled auto-merge (rebase) November 6, 2024 16:13
If we reach the second case of `Zip[T1 <: Tuple, T2 <: Tuple]`,
then we know `(T1, T2)` is disjoint from `(NonEmptyTuple, NonEmptyTuple)`,
from which we can conclude at least one of the two is an `EmptyTuple`.

Addressing scala#19175
Copy link
Member

@sjrd sjrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have enough tests of the various ways Zip can reduce? In particular if there's (S <: Tuple) / EmptyTuple or EmptyTuple / (S <: Tuple) at the end of the chain?

@EugeneFlesselle
Copy link
Contributor Author

Do we have enough tests of the various ways Zip can reduce? In particular if there's (S <: Tuple) / EmptyTuple or EmptyTuple / (S <: Tuple) at the end of the chain?

I've added a test will all possible combinations I could think of.

@EugeneFlesselle EugeneFlesselle merged commit 43d74c8 into scala:main Nov 18, 2024
29 checks passed
@EugeneFlesselle EugeneFlesselle deleted the tuples/zip branch November 18, 2024 09:17
@WojciechMazur WojciechMazur added this to the 3.6.3 milestone Nov 25, 2024
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

Successfully merging this pull request may close these issues.

4 participants