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: docs/docs/reference/match-types.md
+8-26Lines changed: 8 additions & 26 deletions
Original file line number
Diff line number
Diff line change
@@ -84,15 +84,12 @@ Using `can-reduce`, we can now define match type reduction proper in the `reduce
84
84
```
85
85
Match(S, C1, ..., Cn) reduces-to T
86
86
```
87
-
if`Ci_1, ..., Ci_k` is a maximal non-empty subset of `C1, ..., Cn` such that for each `i_j`:
87
+
if
88
88
```
89
-
Match(S, C1, ..., Cn) can-reduce i_j, Ti_j
89
+
Match(S, C1, ..., Cn) can-reduce i, T
90
90
```
91
-
and
92
-
```
93
-
T = Ti_1 & ... & Ti_k
94
-
```
95
-
In other words, a match reduces to the intersection of all right hand sides it can reduce to. This "parallel" notion of reduction was picked for its nice algebraic properties, even though it does not correspond directly to the operational semantics of pattern matching on terms, where the first matching case is chosen.
91
+
and, for `j` in `1..i-1`: `C_j` is disjoint from `C_i`, or else `S` cannot possibly match `C_j`.
92
+
See the section on overlapping patterns for an elaboration of "disjoint" and "cannot possibly match".
96
93
97
94
## Subtyping Rules for Match Types
98
95
@@ -159,26 +156,11 @@ the fact that `s.type` must conform to the pattern's type and derive a GADT cons
159
156
this would be the constraint `x.type <: A`. The new aspect here is that we need GADT constraints over singleton types where
160
157
before we just had constraints over type parameters.
161
158
162
-
Assuming this extension, we can then try to typecheck as usual. E.g. to typecheck the first case `case _: A => 1` of the definition of `m` above, GADT matching will produce the constraint `x.type <: A`. Therefore, `M[x.type]` reduces to the singleton type `1`. The right hand side `1` of the case conforms to this type, so the case typechecks. Typechecking the second case proceeds similarly.
163
-
164
-
However, it turns out that these rules are not enough for type soundness. To see this, assume that `A` and `B` are traits that are both extended by a common class `C`. In this case, and assuming `c: C`, `M[c.type]` reduces to `1 & 2`, but `m(c)` reduces to `1`. So the type of the application `m(c)` does not match the reduced result type of `m`, which means soundness is violated.
165
-
166
-
To plug the soundness hole, we have to tighten the typing rules for match expressions. In the example above we need to also consider the case where the scrutinee `x` conforms to `A` and `B`. In this case, the match expression still returns `1` but the match type `M[x.type]` reduces to `1 & 2`, which means there should be a type error. However, this second check can be omitted if `A` and `B` are types that don't overlap. We can omit the check because in that case there is no scrutinee value `x` that could reduce to `1`, so no discrepancy can arise at runtime.
167
-
168
-
More generally, we proceeed as follows:
169
-
170
-
When typechecking the `i`th case of a match expression
171
-
```
172
-
x match { case P_1 => t_1 ... case P_n => t_n
173
-
```
174
-
where `t_i` has type `T_i` against an expected match type `R`:
175
-
176
-
1. Determine all maximal sequences of
177
-
patterns `P_j_1, ..., P_j_m` that follow `P_i` in the match expression and that do overlap with `P_i`. That is, `P_i, P_j_1, ..., P_j_m` all match at least one common value.
178
-
179
-
2. For each such sequence, verify that `T_i <: R` under the GADT constraint arising from matching the scrutinee `x` against all of the patterns `P_i, P_j_1, ..., P_j_m`.
159
+
Assuming this extension, we can then try to typecheck as usual. E.g. to typecheck the first case `case _: A => 1` of the definition of `m` above, GADT matching will produce the constraint `x.type <: A`. Therefore, `M[x.type]` reduces to the singleton type `1`. The right hand side `1` of the case conforms to this type, so the case typechecks.
180
160
181
-
In the example above, `A` and `B` would be overlapping because they have the common subclass `C`. Hence, we have to check that the right-hand side `1` is a subtype of `M[x.type]` under the assumptions that `x.type <: A` and `x.type <: B`. Under these assumptions `M[x.type]` reduces to `1 & 2`, which gives a type error.
161
+
Typechecking the second case hits a snag, though. In general, the assumption `x.type <: B` is not enough to prove that
162
+
`M[x.type]` reduces to `2`. However we can reduce `M[x.type]` to `2` if the types `A` and `B` do not overlap.
163
+
So correspondence of match terms to match types is feasible only in the case of non-overlapping patterns.
182
164
183
165
For simplicity, we have disregarded the `null` value in this discussion. `null` does not cause a fundamental problem but complicates things somewhat because some forms of patterns do not match `null`.
0 commit comments