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/changed-features/eta-expansion-spec.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -51,7 +51,7 @@ implicit val bla: Double = 1.0
51
51
valbar= foo // val bar: Int => Float = ...
52
52
```
53
53
54
-
## Automatic Eta-Expansion and query types
54
+
## Automatic Eta-Expansion and context types
55
55
56
56
A method with context parameters can be expanded to a value of a context type by writing the expected context type explicitly.
57
57
@@ -66,7 +66,7 @@ val bar: Double ?=> Float = foo(3)
66
66
- If `m` is has an empty argument list (i.e. has type `()R`):
67
67
1. If the expected type is of the form `() => T`, we eta expand.
68
68
2. If m is defined by Java, or overrides a Java defined method, we insert `()`.
69
-
3. Otherwise we issue an error of the form:
69
+
3. Otherwise we issue an error of the form:`method must be called with () argument`
70
70
71
71
Thus, an unapplied method with an empty argument list is only converted to a function when a function type is expected. It is considered best practice to either explicitly apply the method to `()`, or convert it to a function with `() => m()`.
Copy file name to clipboardExpand all lines: docs/_docs/reference/changed-features/main-functions.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -72,7 +72,7 @@ final class happyBirthday:
72
72
caseerror: CLP.ParseError=>CLP.showError(error)
73
73
```
74
74
75
-
**Note**: The `<static>` modifier above expresses that the `main` method is generated
75
+
**Note:** The `<static>` modifier above expresses that the `main` method is generated
76
76
as a static method of class `happyBirthday`. It is not available for user programs in Scala. Regular "static" members are generated in Scala using objects instead.
77
77
78
78
[`@main`](https://scala-lang.org/api/3.x/scala/main.html) methods are the recommended scheme to generate programs that can be invoked from the command line in Scala 3. They replace the previous scheme to write program as objects with a special `App` parent class. In Scala 2, `happyBirthday` could be written also like this:
Copy file name to clipboardExpand all lines: docs/_docs/reference/changed-features/pattern-matching.md
+95-61Lines changed: 95 additions & 61 deletions
Original file line number
Diff line number
Diff line change
@@ -13,26 +13,38 @@ Scala 3 supports a superset of Scala 2 [extractors](https://www.scala-lang.org/f
13
13
Extractors are objects that expose a method `unapply` or `unapplySeq`:
14
14
15
15
```scala
16
-
defunapply[A](x: T)(implicitx: B):U
17
-
defunapplySeq[A](x: T)(implicitx: B):U
16
+
defunapply(x: T):U
17
+
defunapplySeq(x: T):U
18
+
```
19
+
20
+
Where `T` is an arbitrary type, if it is a subtype of the scrutinee's type `Scrut`, a [type test](../other-new-features/type-test.md) is performed before calling the method.
21
+
`U` follows rules described in [Fixed Arity Extractors](#fixed-arity-extractors) and [Variadic Extractors](#variadic-extractors).
22
+
23
+
**Note:**`U` can be the type of the extractor object.
24
+
25
+
`unapply` and `unapplySeq` can actually have a more general signature, allowing for a leading type clause, as well as arbitrarily many using clauses, both before and after the regular term clause, and at most one implicit clause at the end, for example:
Extractors that expose the method `unapply` are called fixed-arity extractors, which
21
32
work with patterns of fixed arity. Extractors that expose the method `unapplySeq` are
22
33
called variadic extractors, which enables variadic patterns.
23
34
24
-
### Fixed-Arity Extractors
35
+
## Fixed-Arity Extractors
36
+
37
+
Fixed-arity extractors expose the following signature (with potential type, using and implicit clauses):
25
38
26
-
Fixed-arity extractors expose the following signature:
27
39
28
40
```scala
29
-
defunapply[A](x: T)(implicitx: B):U
41
+
defunapply(x: T):U
30
42
```
31
43
32
44
The type `U` conforms to one of the following matches:
33
45
34
-
- Boolean match
35
-
- Product match
46
+
-[Boolean match](#boolean-match)
47
+
-[Product match](#product-match)
36
48
37
49
Or `U` conforms to the type `R`:
38
50
@@ -45,53 +57,24 @@ type R = {
45
57
46
58
and `S` conforms to one of the following matches:
47
59
48
-
- single match
49
-
- name-based match
60
+
-[single match](#single-match)
61
+
-[name-based match](#name-based-match)
50
62
51
63
The former form of `unapply` has higher precedence, and _single match_ has higher
52
64
precedence over _name-based match_.
53
65
66
+
**Note:** the `S` in `R` can be `U`.
67
+
54
68
A usage of a fixed-arity extractor is irrefutable if one of the following condition holds:
55
69
56
70
-`U = true`
57
71
- the extractor is used as a product match
58
-
-`U = Some[T]` (for Scala 2 compatibility)
59
72
-`U <: R` and `U <: { def isEmpty: false }`
73
+
-`U = Some[T]`
60
74
61
-
### Variadic Extractors
62
-
63
-
Variadic extractors expose the following signature:
64
-
65
-
```scala
66
-
defunapplySeq[A](x: T)(implicitx: B):U
67
-
```
68
-
69
-
The type `U` conforms to one of the following matches:
70
-
71
-
- sequence match
72
-
- product-sequence match
73
-
74
-
Or `U` conforms to the type `R`:
75
-
76
-
```scala
77
-
typeR= {
78
-
defisEmpty:Boolean
79
-
defget:S
80
-
}
81
-
```
82
-
83
-
and `S` conforms to one of the two matches above.
84
-
85
-
The former form of `unapplySeq` has higher priority, and _sequence match_ has higher
86
-
precedence over _product-sequence match_.
87
-
88
-
A usage of a variadic extractor is irrefutable if one of the following conditions holds:
89
-
90
-
- the extractor is used directly as a sequence match or product-sequence match
91
-
-`U = Some[T]` (for Scala 2 compatibility)
92
-
-`U <: R` and `U <: { def isEmpty: false }`
75
+
**Note:** The last rule is necessary because, for compatibility reasons, `isEmpty` on `Some` has return type `Boolean` rather than `false`, even though it always returns `false`.
93
76
94
-
## Boolean Match
77
+
###Boolean Match
95
78
96
79
-`U =:= Boolean`
97
80
- Pattern-matching on exactly `0` patterns
@@ -111,10 +94,10 @@ object Even:
111
94
// even has an even number of characters
112
95
```
113
96
114
-
## Product Match
97
+
###Product Match
115
98
116
99
-`U <: Product`
117
-
-`N > 0` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1` ... `_N: PN` members in `U`
100
+
-`N > 0` is the maximum number of consecutive (`val` or parameterless `def`) `_1: P1` ... `_N: PN` members in `U`
118
101
- Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN`
119
102
120
103
For example:
@@ -141,9 +124,11 @@ object FirstChars:
141
124
// First: H; Second: i
142
125
```
143
126
144
-
## Single Match
127
+
###Single Match
145
128
146
-
- If there is exactly `1` pattern, pattern-matching on `1` pattern with type `U`
129
+
- Pattern-matching on `1` pattern with type `S`
130
+
131
+
For example, where `Nat <: R`, `S = Int`:
147
132
148
133
<!-- To be kept in sync with tests/new/patmat-spec.scala -->
149
134
@@ -162,27 +147,72 @@ object Nat:
162
147
// 5 is a natural number
163
148
```
164
149
165
-
## Name-based Match
150
+
###Name-based Match
166
151
167
-
-`N > 1` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1 ... _N: PN` members in `U`
152
+
-`S` has `N > 1` members such that they are each `val`s or parameterless `def`s, and named from `_1` with type `P1` to `_N` with type `PN`
153
+
-`S` doesn't have `N+1` members satisfying the previous point, i.e. `N` is maximal
168
154
- Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN`
169
155
156
+
For example, where `U = AlwaysEmpty.type <: R`, `S = NameBased`:
170
157
```scala
171
-
objectProdEmpty:
158
+
objectMyPatternMatcher:
159
+
defunapply(s: String) =AlwaysEmpty
160
+
161
+
objectAlwaysEmpty:
162
+
defisEmpty=true
163
+
defget=NameBased
164
+
165
+
objectNameBased:
172
166
def_1:Int=???
173
167
def_2:String=???
174
-
defisEmpty=true
175
-
defunapply(s: String):this.type=this
176
-
defget=this
177
168
178
169
""match
179
-
caseProdEmpty(_, _) =>???
170
+
caseMyPatternMatcher(_, _) =>???
180
171
case _ => ()
181
172
```
182
173
183
-
## Sequence Match
174
+
## Variadic Extractors
175
+
176
+
Variadic extractors expose the following signature (with potential type, using and implicit clauses):
177
+
178
+
```scala
179
+
defunapplySeq(x: T):U
180
+
```
181
+
182
+
Where `U` has to fullfill the following:
183
+
184
+
1. Set `V := U`
185
+
2.`V` is valid if `V` conforms to one of the following matches:
4. Set `V := S`, and reattempt 2., if it fails `U` is not valid.
196
+
197
+
The `V := U` form of `unapplySeq` has higher priority, and _sequence match_ has higher
198
+
precedence over _product-sequence match_.
199
+
200
+
**Note:** This means `isEmpty` is disregarded if the `V := U` form is valid
201
+
202
+
A usage of a variadic extractor is irrefutable if one of the following conditions holds:
203
+
204
+
- the extractor is used directly as a sequence match or product-sequence match
205
+
-`U <: R` and `U <: { def isEmpty: false }`
206
+
-`U = Some[T]`
207
+
208
+
**Note:** The last rule is necessary because, for compatibility reasons, `isEmpty` on `Some` has return type `Boolean` rather than `false`, even though it always returns `false`.
209
+
210
+
**Note:** Be careful, by the first condition and the note above, it is possible to define an irrefutable extractor with a `def isEmpty: true`.
211
+
This is strongly discouraged and, if found in the wild, is almost certainly a bug.
212
+
213
+
### Sequence Match
184
214
185
-
-`U <: X`, `T2` and `T3` conform to `T1`
215
+
-`V <: X`
186
216
187
217
```scala
188
218
typeX= {
@@ -192,10 +222,12 @@ type X = {
192
222
deftoSeq: scala.Seq[T3]
193
223
}
194
224
```
195
-
225
+
-`T2` and `T3` conform to `T1`
196
226
- Pattern-matching on _exactly_`N` simple patterns with types `T1, T1, ..., T1`, where `N` is the runtime size of the sequence, or
197
227
- Pattern-matching on `>= N` simple patterns and _a vararg pattern_ (e.g., `xs: _*`) with types `T1, T1, ..., T1, Seq[T1]`, where `N` is the minimum size of the sequence.
198
228
229
+
For example, where `V = S`, `U = Option[S] <: R`, `S = Seq[Char]`
230
+
199
231
<!-- To be kept in sync with tests/new/patmat-spec.scala -->
200
232
201
233
```scala
@@ -211,14 +243,16 @@ object CharList:
211
243
// e,x,a,m
212
244
```
213
245
214
-
## Product-Sequence Match
246
+
###Product-Sequence Match
215
247
216
-
-`U <: Product`
217
-
-`N > 0` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1` ... `_N: PN` members in `U`
248
+
-`V <: Product`
249
+
-`N > 0` is the maximum number of consecutive (`val` or parameterless `def`) `_1: P1` ... `_N: PN` members in `V`
218
250
-`PN` conforms to the signature `X` defined in Seq Pattern
219
251
- Pattern-matching on exactly `>= N` patterns, the first `N - 1` patterns have types `P1, P2, ... P(N-1)`,
220
252
the type of the remaining patterns are determined as in Seq Pattern.
221
253
254
+
For example, where `V = S`, `U = Option[S] <: R`, `S = (String, PN) <: Product`, `PN = Seq[Int]`
255
+
222
256
```scala
223
257
classFoo(valname:String, valchildren:Int*)
224
258
objectFoo:
@@ -227,7 +261,7 @@ object Foo:
227
261
228
262
deffoo(f: Foo) = f match
229
263
caseFoo(name, x, y, ns*) =>">= two children."
230
-
caseFoo(name, ns*) =>=>"< two children."
264
+
caseFoo(name, ns*) =>"< two children."
231
265
```
232
266
233
267
There are plans for further simplification, in particular to factor out _product match_
0 commit comments