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
Note the swap of the two parameters `x` and `xs` when translating
56
60
the right-associative operator `+:` to an extension method. This is analogous
57
61
to the implementation of right binding operators as normal methods. The Scala
@@ -73,13 +77,15 @@ the two swaps cancel each other out).
73
77
74
78
If an extension method has type parameters, they come immediately after `extension` and are followed by the extended parameter.
75
79
When calling a generic extension method, any explicitly given type arguments follow the method name. So the `second` method could be instantiated as follows.
80
+
76
81
```scala
77
82
List(1, 2, 3).second[Int]
78
83
```
79
-
Of course, the type argument here would usually be left out since it can be inferred.
80
84
85
+
Of course, the type argument here would usually be left out since it can be inferred.
81
86
82
87
Extensions can also take using clauses. For instance, the `+` extension above could equivalently be written with a using clause:
88
+
83
89
```scala
84
90
extension [T](x: T)(usingn: Numeric[T])
85
91
def- (y: T):T= n.minus(x, y)
@@ -94,6 +100,7 @@ Sometimes, one wants to define several extension methods that share the same
94
100
left-hand parameter type. In this case one can "pull out" the common parameters into
95
101
a single extension and enclose all methods in braces or an indented region following a '`:`'.
96
102
Example:
103
+
97
104
```scala
98
105
extension (ss: Seq[String])
99
106
@@ -109,6 +116,7 @@ assuming the common extended value `ss` as receiver.
109
116
110
117
Collective extensions like these are a shorthand for individual extensions
111
118
where each method is defined separately. For instance, the first extension above expands to
119
+
112
120
```scala
113
121
extension (ss: Seq[String])
114
122
deflongestStrings:Seq[String] =
@@ -118,7 +126,9 @@ extension (ss: Seq[String])
118
126
extension (ss: Seq[String])
119
127
deflongestString:String= ss.longestStrings.head
120
128
```
129
+
121
130
Collective extensions also can take type parameters and have using clauses. Example
131
+
122
132
```scala
123
133
extension [T](xs: List[T])(usingOrdering[T])
124
134
defsmallest(n: Int):List[T] = xs.sorted.take(n)
@@ -167,14 +177,17 @@ trait SafeDiv:
167
177
case (Some(d), Some(r)) =>Some((d, r))
168
178
case _ =>None
169
179
```
180
+
170
181
By the second rule, an extension method can be made available by defining a given instance containing it, like this:
182
+
171
183
```scala
172
184
givenops1 as IntOps// brings safeMod into scope
173
185
174
186
1.safeMod(2)
175
187
```
176
188
177
189
By the third and fourth rule, an extension method is available if it is in the implicit scope of the receiver type or in a given instance in that scope. Example:
190
+
178
191
```scala
179
192
classList[T]:
180
193
...
@@ -204,53 +217,58 @@ Assume a selection `e.m[Ts]` where `m` is not a member of `e`, where the type ar
204
217
2. If the first rewriting does not typecheck with expected type `T`,
205
218
and there is an extension method `m` in some eligible object `o`, the selection is rewritten to `o.extension_m[Ts](e)`. An object `o` is _eligible_ if
206
219
207
-
-`o` forms part of the implicit scope of `T`, or
208
-
-`o` is a given instance that is visible at the point of the application, or
209
-
-`o` is a given instance in the implicit scope of `T`.
220
+
-`o` forms part of the implicit scope of `T`, or
221
+
-`o` is a given instance that is visible at the point of the application, or
222
+
-`o` is a given instance in the implicit scope of `T`.
210
223
211
224
This second rewriting is attempted at the time where the compiler also tries an implicit conversion
212
225
from `T` to a type containing `m`. If there is more than one way of rewriting, an ambiguity error results.
213
226
214
227
An extension method can also be used as an identifier by itself. If an identifier `m` does not
215
228
resolve, the identifier is rewritten to:
216
229
217
-
-`x.m` if the identifier appears in an extension with parameter `x`
218
-
-`this.m` otherwise
230
+
-`x.m` if the identifier appears in an extension with parameter `x`
231
+
-`this.m` otherwise
219
232
220
233
and the rewritten term is again tried as an application of an extension method. Example:
234
+
221
235
```scala
222
-
extension (s: String)
223
-
defposition(ch: Char, n: Int):Int=
224
-
if n < s.length && s(n) != ch then position(ch, n +1)
225
-
else n
236
+
extension (s: String)
237
+
defposition(ch: Char, n: Int):Int=
238
+
if n < s.length && s(n) != ch then position(ch, n +1)
239
+
else n
226
240
```
241
+
227
242
The recursive call `position(ch, n + 1)` expands to `s.position(ch, n + 1)` in this case. The whole extension method rewrites to
0 commit comments