@@ -43,64 +43,65 @@ Let's define some abstractions on the possible results of this pattern matching
43
43
type Matching = Option [Tuple ]
44
44
type Env
45
45
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 )(_ && _)
51
51
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
53
54
54
55
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
55
56
56
57
def equivalent (s1 : Symbol , s2 : Symbol ) given Env : Env
57
58
```
58
59
59
- The implementation of ` matches `
60
+ The implementation of ` =#= `
60
61
61
62
| Tree | Pattern | Returns |
62
63
| :-----------------------: | :-------------------------: | :---------- |
63
64
| 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 `
85
86
| | |
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 `
87
88
| | |
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 `
93
94
94
95
95
96
| Pattern inside the quote | Pattern | Returns |
96
97
| :-------------------------: | :--------------------------: | :------------- |
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 `
104
105
105
106
<!-- TODO spec for the environment from patterns propagated to the result -->
106
107
0 commit comments