You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/match-types-spec.md
+36Lines changed: 36 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -419,6 +419,42 @@ It means that if we make the scrutinee of a match type more precise (a subtype)
419
419
Note: if `⋔` were a "true" disjointness relationship, and not a *provably*-disjoint relationship, that property would trivially hold based on elementary set theoretic properties.
420
420
It would amount to proving that if `S ⊆ T` and `T ⋂ U = ∅`, then `S ⋂ U = ∅`.
421
421
422
+
#### Reduction
423
+
424
+
The final piece of the match types puzzle is to define the reduction as a whole.
425
+
426
+
In addition to matching and `provablyDisjoint`, the existing algorithm relies on a `provablyEmpty` property for a single type.
427
+
It was added a safeguard against matching an empty (`Nothing`) scrutinee.
428
+
The problem with doing so is that an empty scrutinee will be considered *both* as matching the pattern *and* as provably disjoint from the pattern.
429
+
This can result in the match type reducing to different cases depending on the context.
430
+
To sidestep this issue, the current algorithm refuses to consider a scrutinee that is `provablyEmpty`.
431
+
432
+
If we wanted to keep that strategy, we would also have to specify `provablyEmpty` and prove some properties about it.
433
+
Instead, we choose a much simpler and safer strategy: we always test both matching *and*`provablyDisjoint`.
434
+
When both apply, we deduce that the scrutinee is empty is refuse to reduce the match type.
435
+
436
+
Therefore, in summary, the whole reduction algorithm works as follows.
437
+
The result of reducing `X match { case P1 => R1; ...; case Pn => Rn }` can be a type, undefined, or a compile error.
438
+
For `n >= 1`, it is specified as:
439
+
440
+
* If `X` matches `P1` with type capture instantiations `[...ts => ts']`:
441
+
* If `X ⋔ P1`, do not reduce.
442
+
* Otherwise, reduce as `[...ts => ts']R1`.
443
+
* Otherwise,
444
+
* If `X ⋔ P1`, the result of reducing `X match { case P2 => R2; ...; case Pn => Rn }` (i.e., proceed with subsequent cases).
445
+
* Otherwise, do not reduce.
446
+
447
+
The reduction of an "empty" match type `X match { }` (which cannot be written in user programs) is a compile error.
448
+
449
+
#### Subtyping
450
+
451
+
As is already the case in the existing system, match types tie into subtyping as follows:
452
+
453
+
*`X match { ... } <: T` if `X match { ... }` reduces to `S1` and `S1 <: T`
454
+
*`S <: X match { ... }` if `X match { ... }` reduces to `T1` and `S <: T1`
455
+
*`X match { ... } <: T` if `X match { ... }` has the upper bound `H` and `H <: T`
456
+
*`X match { case P1 => A1; ...; case Pn => An } <: Y match { case Q1 => B1; ...; Qn => Bn }` if `X =:= Y` and `Pi =:= Qi` for each `i` and `Ai <: Bi` for each `i`
457
+
422
458
### Compatibility
423
459
424
460
Compatibility is inherently tricky to evaluate for this proposal, and even to define.
0 commit comments