Skip to content

Commit ef107bf

Browse files
committed
Update syntax to match implementation
1 parent 4596607 commit ef107bf

File tree

1 file changed

+42
-41
lines changed

1 file changed

+42
-41
lines changed

docs/docs/reference/other-new-features/quoted-pattern-spec.md

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,64 +43,65 @@ Let's define some abstractions on the possible results of this pattern matching
4343
type Matching = Option[Tuple]
4444
type Env
4545

46-
def noMatch = None
47-
def emptyMatch = Some(()) // aka Some(Tuple0())
48-
def match[T](x: T) = Some(Tuple1(x))
49-
def (x: Matching) ++ (y: Matching) = if (x == None || y == None) None else Some(x.get ++ y.get)
50-
def fold[T](m: Mattching*) given Env: Matching = m.fold(emptyMatch)(_ ++ _)
46+
def notMatched = None
47+
def matched = Some(()) // aka Some(Tuple0())
48+
def matched[T](x: T) = Some(Tuple1(x))
49+
def (x: Matching) && (y: Matching) = if (x == None || y == None) None else Some(x.get ++ y.get)
50+
def fold[T](m: Mattching*) given Env: Matching = m.fold(matched)(_ && _)
5151

52-
def matches(scrutinee: Tree, pattern: Tree) given Env: Matching // described by cases in the tables below
52+
// `a =#= b` stands for `a` matches `b`
53+
def (scrutinee: Tree) =#= pattern: Tree) given Env: Matching // described by cases in the tables below
5354

5455
def envWith(equiv: (Symbol, Symbol)*) given Env: Env // Adds to the current environment the fact that s1 from the scrutinee is equivalent to s2 in the pattern
5556

5657
def equivalent(s1: Symbol, s2: Symbol) given Env: Env
5758
```
5859

59-
The implementation of `matches`
60+
The implementation of `=#=`
6061

6162
| Tree | Pattern | Returns |
6263
| :-----------------------: | :-------------------------: | :---------- |
6364
| Term `a` | `patternHole[X]` | `match(quoted.Expr[X]('a))` if type of `a` is a subtype of `X`
64-
| `val a: A` | `@patternBindHole val x: X` | `match(quoted.Bind[X](a.sym)) ++ matches('{val a: A}, '{val x: X})`
65-
| Literal `a` | Literal `x` | `emptyMatch` if value of `a` is equal to the value of `x`
66-
| `a` | `x` | `emptyMatch` if `equivalent(a.sym, x.sym)`
67-
| `a.b` | `x.y` | `matches('a, 'x)` if `equivalent(b.sym, y.sym)`
68-
| `a: A` | `x: X` | `matches('a, 'x) ++ matches('[A], '[X])`
69-
| `fa(.. ai ..)` | `fx(.. xi ..)` | `matches('fa, 'fx) ++ fold(.. matches('ai, 'xi) ..)`
70-
| `fa[.. Ai ..]` | `fx[.. Xi ..]` | `matches('fa, 'fx) ++ fold(.. matches('[Ai], '[Xi]) ..)`
71-
| `{.. ai ..}` | `{.. xi ..}` | `fold(.. matches('ai, 'xi) ..)`
72-
| `if (a) b else c` | `if (x) y else z` | `matches('a, 'x) ++ matches('b, 'y) ++ matches('c, 'z)`
73-
| `while (a) b` | `while (x) y` | `matches('a, 'x) ++ matches('b, 'y)`
74-
| Assignment `a = b` | Assignment `x = y` | `matches('b, 'y)` if `matches('a, 'x).nonEmpty`
75-
| Named argument<br>`n = a` | Named argument<br>`m = x` | `matches('a, 'x)`
76-
| `Seq(.. ai ..): _*` | `Seq(.. xi ..): _*` | `fold(.. matches('ai, 'xi) ..)`
77-
| `new A` | `new X` | `matches('[A], '[X])`
78-
| `this` | `this` | `emptyMatch` if both refer to the same symbol
79-
| `a.super[B]` | `x.super[Y]` | `matches('a, 'x)` if `B` equals `Y`
80-
| `val a: A = b`<br>`lazy val a: A = b`<br>`var a: A = b` | `val x: X = y`<br>`lazy val x: X = y`<br>`var x: X = y` | `matches('[A], '[X]) ++ matches('b, 'y) given envWith(a.sym -> b.sym)`
81-
| `def a[..Ai..](.. bij: Bij ..): A = c` | `def x[..Xi..](.. yij: Yij ..): X = z` | `fold(..matches('[Ai], '[Xi])..) ++ fold(.. matches('bij, 'yij) ++ matches('[Bij], '[Yij]) ..) ++ matches('[A], '[X]) ++ matches('c, 'z) given envWith(a.sym -> b.sym, .. bij.sym -> yij.sym ..)`
82-
| `(.. ai: Ai ..) => b` | `(.. xi: Xi ..) => y` | `fold(.. matches('ai, 'xi) ++ matches('[Ai], '[Xi]) ..) ++ matches('b, 'y) given envWith(.. ai.sym -> xi.sym ..)`
83-
| `a match { .. bi .. }` | `x match { .. yi .. }` | `matches('a, 'x) ++ fold(.. matches('bi, 'yi) ..)`
84-
| `try a catch { .. bi .. } finally ci` | `try x catch { .. yi .. } finally z` | `matches('a, 'x) ++ fold(.. matches('bi, 'yi) ..) ++ matches('c, 'z)`
65+
| `val a: A` | `@patternBindHole val x: X` | `match(quoted.Bind[X](a.sym)) && '{val a: A} =#= '{val x: X}`
66+
| Literal `a` | Literal `x` | `matched` if value of `a` is equal to the value of `x`
67+
| `a` | `x` | `matched` if `equivalent(a.sym, x.sym)`
68+
| `a.b` | `x.y` | `'a =#= 'x` if `equivalent(b.sym, y.sym)`
69+
| `a: A` | `x: X` | `'a =#= 'x && '[A] =#= '[X]`
70+
| `fa(.. ai ..)` | `fx(.. xi ..)` | `'fa =#= 'fx && fold(.. 'ai =#= 'xi) ..)`
71+
| `fa[.. Ai ..]` | `fx[.. Xi ..]` | `'fa =#= 'fx && fold(.. '[Ai] =#= '[Xi] ..)`
72+
| `{.. ai ..}` | `{.. xi ..}` | `fold(.. 'ai =#= 'xi ..)`
73+
| `if (a) b else c` | `if (x) y else z` | `'a =#= 'x && 'b =#= 'y && 'c =#= 'z`
74+
| `while (a) b` | `while (x) y` | `'a =#= 'x && 'b =#= 'y`
75+
| Assignment `a = b` | Assignment `x = y` | `'b =#= 'y` if `'a =#= 'x.nonEmpty`
76+
| Named argument<br>`n = a` | Named argument<br>`m = x` | `'a =#= 'x`
77+
| `Seq(.. ai ..): _*` | `Seq(.. xi ..): _*` | `fold(.. 'ai =#= 'xi ..)`
78+
| `new A` | `new X` | `'[A] =#= '[X]`
79+
| `this` | `this` | `matched` if both refer to the same symbol
80+
| `a.super[B]` | `x.super[Y]` | `'a =#= 'x` if `B` equals `Y`
81+
| `val a: A = b`<br>`lazy val a: A = b`<br>`var a: A = b` | `val x: X = y`<br>`lazy val x: X = y`<br>`var x: X = y` | `'[A] =#= '[X] && 'b =#= 'y given envWith(a.sym -> b.sym)`
82+
| `def a[..Ai..](.. bij: Bij ..): A = c` | `def x[..Xi..](.. yij: Yij ..): X = z` | `fold(..'[Ai] =#= '[Xi]..) && fold(.. 'bij =#= 'yij && '[Bij] =#= '[Yij] ..) && '[A] =#= '[X] && 'c =#= 'z given envWith(a.sym -> b.sym, .. bij.sym -> yij.sym ..)`
83+
| `(.. ai: Ai ..) => b` | `(.. xi: Xi ..) => y` | `fold(.. 'ai =#= 'xi && '[Ai] =#= '[Xi] ..) && 'b =#= 'y given envWith(.. ai.sym -> xi.sym ..)`
84+
| `a match { .. bi .. }` | `x match { .. yi .. }` | `'a =#= 'x && fold(.. 'bi =#= 'yi ..)`
85+
| `try a catch { .. bi .. } finally ci` | `try x catch { .. yi .. } finally z` | `'a =#= 'x && fold(.. 'bi =#= 'yi ..) && 'c =#= 'z`
8586
| | |
86-
| `case a if b => c` | `case x if y => z` | `matches('a, 'x) ++ matches('b, 'y) ++ matches(c, z)`
87+
| `case a if b => c` | `case x if y => z` | `'a =#= 'x && 'b =#= 'y && c =#= z`
8788
| | |
88-
| Inferred `A` | Inferred `X` | `emptyMatch` if `A <:< X`
89-
| `A[.. Bi ..]` | `X[.. Yi ..]` | `emptyMatch` if `(matches('[A], '[X]) ++ fold(.. matches('[Bi], '[Yi]) ..)).nonEmpty`
90-
| `A @annot` | `X` | `matches('[A], '[X])`
91-
| `A` | `X @annot` | `matches('[A], '[X])`
92-
| | | `noMatch`
89+
| Inferred `A` | Inferred `X` | `matched` if `A <:< X`
90+
| `A[.. Bi ..]` | `X[.. Yi ..]` | `matched` if `('[A] && '[X] && fold(.. '[Bi] =#= '[Yi] ..)).nonEmpty`
91+
| `A @annot` | `X` | `'[A] =#= '[X]`
92+
| `A` | `X @annot` | `'[A] && '[X]`
93+
| | | `notMatched`
9394

9495

9596
| Pattern inside the quote | Pattern | Returns |
9697
| :-------------------------: |:--------------------------: | :------------- |
97-
| Value `a` | Value `x` | `matches('a, 'x)`
98-
| `a: A` | `x: X` | `matches('[A], '[X])`
99-
| `a @ b` | `x @ y` | `matches('b, 'y) given envWith(a.sym -> b.sym)`
100-
| Unapply `a(..bi..)(..ci..)` | Unapply `x(..yi..)(..zi..)` | `matches('a, 'x) ++ fold(.. matches('bi, 'yi) ..) ++ fold(.. matches('ci, 'zi) ..)`
101-
| `.. | ai | ..` | `.. | xi | ..` | `fold(.. matches('ai, 'xi) ..)`
102-
| `_` | `_` | `emptyMatch`
103-
| | | `noMatch`
98+
| Value `a` | Value `x` | `'a =#= 'x`
99+
| `a: A` | `x: X` | `'[A] && '[X]`
100+
| `a @ b` | `x @ y` | `'b =#= 'y given envWith(a.sym -> b.sym)`
101+
| Unapply `a(..bi..)(..ci..)` | Unapply `x(..yi..)(..zi..)` | `'a =#= 'x && fold(.. 'bi =#= 'yi ..) && fold(.. 'ci =#= 'zi ..)`
102+
| `.. | ai | ..` | `.. | xi | ..` | `fold(.. 'ai =#= 'xi ..)`
103+
| `_` | `_` | `matched`
104+
| | | `notMatched`
104105

105106
<!-- TODO spec for the environment from patterns propagated to the result -->
106107

0 commit comments

Comments
 (0)