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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

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
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.

3 participants