Skip to content

Commit 3c6b360

Browse files
committed
Add the complete reduction algorithm.
1 parent cc9c90a commit 3c6b360

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

content/match-types-spec.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,42 @@ It means that if we make the scrutinee of a match type more precise (a subtype)
419419
Note: if `` were a "true" disjointness relationship, and not a *provably*-disjoint relationship, that property would trivially hold based on elementary set theoretic properties.
420420
It would amount to proving that if `S ⊆ T` and `T ⋂ U = ∅`, then `S ⋂ U = ∅`.
421421

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+
422458
### Compatibility
423459

424460
Compatibility is inherently tricky to evaluate for this proposal, and even to define.

0 commit comments

Comments
 (0)