2022-09-29 23:33:23 +03:00
|
|
|
```ucm:hide
|
|
|
|
.> builtins.merge
|
|
|
|
```
|
|
|
|
|
|
|
|
# Basics
|
2023-03-02 18:04:36 +03:00
|
|
|
## non-exhaustive patterns
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
unique type T = A | B | C
|
|
|
|
|
|
|
|
test : T -> ()
|
|
|
|
test = cases
|
2023-02-28 00:12:10 +03:00
|
|
|
A -> ()
|
2022-09-29 23:33:23 +03:00
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
```unison:error
|
|
|
|
unique type T = A | B
|
|
|
|
|
|
|
|
test : (T, Optional T) -> ()
|
|
|
|
test = cases
|
|
|
|
(A, Some _) -> ()
|
|
|
|
(A, None) -> ()
|
|
|
|
(B, Some A) -> ()
|
|
|
|
(B, None) -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
## redundant patterns
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
unique type T = A | B | C
|
|
|
|
|
|
|
|
test : T -> ()
|
|
|
|
test = cases
|
2023-02-28 00:12:10 +03:00
|
|
|
A -> ()
|
|
|
|
B -> ()
|
|
|
|
C -> ()
|
|
|
|
_ -> ()
|
2022-09-29 23:33:23 +03:00
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
```unison:error
|
|
|
|
unique type T = A | B
|
|
|
|
|
|
|
|
test : (T, Optional T) -> ()
|
|
|
|
test = cases
|
|
|
|
(A, Some _) -> ()
|
|
|
|
(A, None) -> ()
|
|
|
|
(B, Some _) -> ()
|
|
|
|
(B, None) -> ()
|
|
|
|
(A, Some A) -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
# Uninhabited patterns
|
|
|
|
|
|
|
|
match is complete without covering uninhabited patterns
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison
|
|
|
|
unique type V =
|
|
|
|
|
|
|
|
test : Optional (Optional V) -> ()
|
|
|
|
test = cases
|
|
|
|
None -> ()
|
|
|
|
Some None -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
uninhabited patterns are reported as redundant
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
unique type V =
|
|
|
|
|
2023-03-08 20:24:21 +03:00
|
|
|
test0 : V -> ()
|
|
|
|
test0 = cases
|
|
|
|
_ -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
```unison:error
|
|
|
|
unique type V =
|
|
|
|
|
2022-09-29 23:33:23 +03:00
|
|
|
test : Optional (Optional V) -> ()
|
|
|
|
test = cases
|
|
|
|
None -> ()
|
|
|
|
Some None -> ()
|
|
|
|
Some _ -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
# Guards
|
|
|
|
|
|
|
|
## Incomplete patterns due to guards should be reported
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
test : () -> ()
|
|
|
|
test = cases
|
|
|
|
() | false -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
```unison:error
|
|
|
|
test : Optional Nat -> Nat
|
|
|
|
test = cases
|
|
|
|
None -> 0
|
|
|
|
Some x
|
|
|
|
| isEven x -> x
|
|
|
|
```
|
|
|
|
|
|
|
|
## Complete patterns with guards should be accepted
|
|
|
|
```unison:error
|
|
|
|
test : Optional Nat -> Nat
|
|
|
|
test = cases
|
|
|
|
None -> 0
|
|
|
|
Some x
|
|
|
|
| isEven x -> x
|
|
|
|
| otherwise -> 0
|
|
|
|
```
|
|
|
|
|
|
|
|
# Pattern instantiation depth
|
|
|
|
|
|
|
|
Uncovered patterns are only instantiated as deeply as necessary to
|
|
|
|
distinguish them from existing patterns.
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
unique type T = A | B | C
|
|
|
|
|
|
|
|
test : Optional (Optional T) -> ()
|
|
|
|
test = cases
|
|
|
|
None -> ()
|
|
|
|
Some None -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
```unison:error
|
|
|
|
unique type T = A | B | C
|
|
|
|
|
|
|
|
test : Optional (Optional T) -> ()
|
|
|
|
test = cases
|
|
|
|
None -> ()
|
|
|
|
Some None -> ()
|
|
|
|
Some (Some A) -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
# Literals
|
2023-03-02 18:04:36 +03:00
|
|
|
|
|
|
|
## Non-exhaustive
|
|
|
|
|
|
|
|
Nat
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
test : Nat -> ()
|
|
|
|
test = cases
|
|
|
|
0 -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
Boolean
|
|
|
|
```unison:error
|
|
|
|
test : Boolean -> ()
|
|
|
|
test = cases
|
|
|
|
true -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
## Exhaustive
|
|
|
|
|
|
|
|
Nat
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison
|
|
|
|
test : Nat -> ()
|
|
|
|
test = cases
|
|
|
|
0 -> ()
|
|
|
|
_ -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
Boolean
|
|
|
|
```unison
|
2022-09-29 23:33:23 +03:00
|
|
|
test : Boolean -> ()
|
|
|
|
test = cases
|
|
|
|
true -> ()
|
2023-03-02 18:04:36 +03:00
|
|
|
false -> ()
|
2022-09-29 23:33:23 +03:00
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
# Redundant
|
|
|
|
|
|
|
|
Nat
|
|
|
|
```unison:error
|
|
|
|
test : Nat -> ()
|
2022-09-29 23:33:23 +03:00
|
|
|
test = cases
|
2023-03-02 18:04:36 +03:00
|
|
|
0 -> ()
|
|
|
|
0 -> ()
|
|
|
|
_ -> ()
|
2022-09-29 23:33:23 +03:00
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
Boolean
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
test : Boolean -> ()
|
|
|
|
test = cases
|
|
|
|
true -> ()
|
|
|
|
false -> ()
|
|
|
|
_ -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
# Sequences
|
2023-03-02 18:04:36 +03:00
|
|
|
|
|
|
|
## Exhaustive
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison
|
|
|
|
test : [()] -> ()
|
|
|
|
test = cases
|
|
|
|
[] -> ()
|
|
|
|
x +: xs -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
## Non-exhaustive
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
test : [()] -> ()
|
|
|
|
test = cases
|
|
|
|
[] -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
```unison:error
|
|
|
|
test : [()] -> ()
|
|
|
|
test = cases
|
|
|
|
x +: xs -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
```unison:error
|
|
|
|
test : [()] -> ()
|
|
|
|
test = cases
|
|
|
|
xs :+ x -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
```unison:error
|
|
|
|
test : [()] -> ()
|
|
|
|
test = cases
|
|
|
|
x0 +: (x1 +: xs) -> ()
|
|
|
|
[] -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
```unison:error
|
|
|
|
test : [()] -> ()
|
|
|
|
test = cases
|
|
|
|
[] -> ()
|
|
|
|
x0 +: [] -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
## Uninhabited
|
|
|
|
|
|
|
|
`Cons` is not expected since `V` is uninhabited
|
|
|
|
```unison
|
|
|
|
unique type V =
|
|
|
|
|
|
|
|
test : [V] -> ()
|
|
|
|
test = cases
|
|
|
|
[] -> ()
|
|
|
|
```
|
|
|
|
|
|
|
|
## Length restrictions can equate cons and nil patterns
|
|
|
|
|
|
|
|
Here the first pattern matches lists of length two or greater, the
|
|
|
|
second pattern matches lists of length 0. The third case matches when the
|
|
|
|
final element is `false`, while the fourth pattern matches when the
|
|
|
|
first element is `true`. However, the only possible list length at
|
|
|
|
the third or fourth clause is 1, so the first and final element must
|
|
|
|
be equal. Thus, the pattern match is exhaustive.
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison
|
|
|
|
test : [Boolean] -> ()
|
|
|
|
test = cases
|
|
|
|
[a, b] ++ xs -> ()
|
|
|
|
[] -> ()
|
|
|
|
xs :+ false -> ()
|
|
|
|
true +: xs -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
This is the same idea as above but shows that fourth match is redundant.
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
test : [Boolean] -> ()
|
|
|
|
test = cases
|
|
|
|
[a, b] ++ xs -> ()
|
|
|
|
[] -> ()
|
|
|
|
xs :+ true -> ()
|
|
|
|
true +: xs -> ()
|
|
|
|
_ -> ()
|
|
|
|
```
|
|
|
|
|
2023-03-02 18:04:36 +03:00
|
|
|
This is another similar example. The first pattern matches lists of
|
|
|
|
length 5 or greater. The second matches lists of length 4 or greater where the
|
|
|
|
first and third element are true. The third matches lists of length 4
|
|
|
|
or greater where the final 4 elements are `true, false, true, false`.
|
|
|
|
The list must be exactly of length 4 to arrive at the second or third
|
|
|
|
clause, so the third pattern is redundant.
|
2022-09-29 23:33:23 +03:00
|
|
|
```unison:error
|
|
|
|
test : [Boolean] -> ()
|
|
|
|
test = cases
|
|
|
|
[a, b, c, d, f] ++ xs -> ()
|
|
|
|
[true, _, true, _] ++ _ -> ()
|
|
|
|
_ ++ [true, false, true, false] -> ()
|
|
|
|
_ -> ()
|
|
|
|
```
|