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
@@ -42,7 +42,7 @@ A trait or class can appear in a `derives` clause if its companion object define
42
42
```scala
43
43
defderived[T] givenGeneric[T] = ...
44
44
```
45
-
That is, the `derived` method takes an inferable parameter of type `Generic` that determines the _shape_ of the deriving type `T` and it computes the typeclass implementation according to that shape. Evidence for`Generic` is generated automatically for any type that derives a typeclass with a `derived`
45
+
That is, the `derived` method takes an inferable parameter of type `Generic` that determines the _shape_ of the deriving type `T` and it computes the typeclass implementation according to that shape. An implicit instance of`Generic` is generated automatically for any type that derives a typeclass with a `derived`
46
46
method that refers to `Generic`. One can also derive `Generic` alone, which means a `Generic` instance is generated without any other type class instances. E.g.:
47
47
```scala
48
48
sealedtraitParseResult[T] derivesGeneric
@@ -94,9 +94,9 @@ is represented as `T *: Unit` since there is no direct syntax for such tuples: `
94
94
95
95
### The Generic Typeclass
96
96
97
-
For every class `C[T_1,...,T_n]` with a `derives` clause, the compiler generates in the companion object of `C`evidence for`Generic[C[T_1,...,T_n]]` that follows the outline below:
97
+
For every class `C[T_1,...,T_n]` with a `derives` clause, the compiler generates in the companion object of `C`an implicit instance of`Generic[C[T_1,...,T_n]]` that follows the outline below:
We need to implement a method `Eql.derived` that produces an instance of `Eql[T]` provided
218
-
there exists evidence of type`Generic[T]`. Here's a possible solution:
217
+
We need to implement a method `Eql.derived` that produces an implicit instance of `Eql[T]` provided
218
+
there exists an implicit instance of`Generic[T]`. Here's a possible solution:
219
219
```scala
220
220
inlinedefderived[T] given (ev: Generic[T]):Eql[T] =newEql[T] {
221
221
defeql(x: T, y: T):Boolean= {
@@ -234,7 +234,7 @@ there exists evidence of type `Generic[T]`. Here's a possible solution:
234
234
The implementation of the inline method `derived` creates an instance of `Eql[T]` and implements its `eql` method. The right-hand side of `eql` mixes compile-time and runtime elements. In the code above, runtime elements are marked with a number in parentheses, i.e
235
235
`(1)`, `(2)`, `(3)`. Compile-time calls that expand to runtime code are marked with a number in brackets, i.e. `[4]`, `[5]`. The implementation of `eql` consists of the following steps.
236
236
237
-
1. Map the compared values `x` and `y` to their mirrors using the `reflect` method of the implicitly passed `Generic`evidence`(1)`, `(2)`.
237
+
1. Map the compared values `x` and `y` to their mirrors using the `reflect` method of the implicitly passed `Generic`instance`(1)`, `(2)`.
238
238
2. Match at compile-time against the shape of the ADT given in `ev.Shape`. Dotty does not have a construct for matching types directly, but we can emulate it using an `inline` match over an `erasedValue`. Depending on the actual type `ev.Shape`, the match will reduce at compile time to one of its two alternatives.
239
239
3. If `ev.Shape` is of the form `Cases[alts]` for some tuple `alts` of alternative types, the equality test consists of comparing the ordinal values of the two mirrors `(3)` and, if they are equal, comparing the elements of the case indicated by that ordinal value. That second step is performed by code that results from the compile-time expansion of the `eqlCases` call `[4]`.
240
240
4. If `ev.Shape` is of the form `Case[elems]` for some tuple `elems` for element types, the elements of the case are compared by code that results from the compile-time expansion of the `eqlElems` call `[5]`.
@@ -298,14 +298,14 @@ non-empty, say of form `elem *: elems1`, the following code is produced:
298
298
299
299
The last, and in a sense most interesting part of the derivation is the comparison of a pair of element values in `tryEql`. Here is the definition of this method:
300
300
```scala
301
-
inlinedeftryEql[T](x: T, y: T) =implicitmatch {
301
+
inlinedeftryEql[T](x: T, y: T) =instancematch {
302
302
caseev: Eql[T] =>
303
303
ev.eql(x, y) // (15)
304
304
case _ =>
305
305
error("No `Eql` instance was found for $T")
306
306
}
307
307
```
308
-
`tryEql` is an inline method that takes an element type `T` and two element values of that type as arguments. It is defined using an `evidence match` that tries to find evidence for`Eql[T]`. If an instance `ev` is found, it proceeds by comparing the arguments using `ev.eql`. On the other hand, if no instance is found
308
+
`tryEql` is an inline method that takes an element type `T` and two element values of that type as arguments. It is defined using an `instance match` that tries to find an implicit instance of`Eql[T]`. If an instance `ev` is found, it proceeds by comparing the arguments using `ev.eql`. On the other hand, if no instance is found
309
309
this signals a compilation error: the user tried a generic derivation of `Eql` for a class with an element type that does not support an `Eql` instance itself. The error is signaled by
310
310
calling the `error` method defined in `scala.compiletime`.
311
311
@@ -314,7 +314,7 @@ calling the `error` method defined in `scala.compiletime`.
314
314
**Example:** Here is a slightly polished and compacted version of the code that's generated by inline expansion for the derived `Eql` instance of class `Tree`.
315
315
316
316
```scala
317
-
evidence [T] given (elemEq: Eql[T]) forEql[Tree[T]] {
317
+
instance [T] given (elemEq: Eql[T]) ofEql[Tree[T]] {
318
318
defeql(x: Tree[T], y: Tree[T]):Boolean= {
319
319
valev= the[Generic[Tree[T]]]
320
320
valmx= ev.reflect(x)
@@ -333,21 +333,22 @@ evidence [T] given (elemEq: Eql[T]) for Eql[Tree[T]] {
333
333
}
334
334
```
335
335
336
-
One important difference between this approach and Scala-2 typeclass derivation frameworks such as Shapeless or Magnolia is that no automatic attempt is made to generate typeclass instances of elements recursively using the generic derivation framework. There must be an evidence value of type `Eql[T]` (which can of course be produced in turn using `Eql.derived`), or the compilation will fail. The advantage of this more restrictive approach to typeclass derivation is that it avoids uncontrolled transitive typeclass derivation by design. This keeps code sizes smaller, compile times lower, and is generally more predictable.
336
+
One important difference between this approach and Scala-2 typeclass derivation frameworks such as Shapeless or Magnolia is that no automatic attempt is made to generate typeclass instances of elements recursively using the generic derivation framework. There must be an implicit instance of type `Eql[T]` (which can of course be produced in turn using `Eql.derived`), or the compilation will fail. The advantage of this more restrictive approach to typeclass derivation is that it avoids uncontrolled transitive typeclass derivation by design. This keeps code sizes smaller, compile times lower, and is generally more predictable.
337
337
338
338
### Derived Instances Elsewhere
339
339
340
340
Sometimes one would like to derive a typeclass instance for an ADT after the ADT is defined, without being able to change the code of the ADT itself.
341
341
To do this, simply define an instance with the `derived` method of the typeclass as right-hand side. E.g, to implement `Ordering` for `Option`, define:
Copy file name to clipboardExpand all lines: docs/docs/reference/contextual-instance/extension-methods.md
+11-11Lines changed: 11 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ When is an extension method applicable? There are two possibilities.
36
36
37
37
- An extension method is applicable if it is visible under a simple name, by being defined
38
38
or inherited or imported in a scope enclosing the application.
39
-
- An extension method is applicable if it is a member of some evidence value at the point of the application.
39
+
- An extension method is applicable if it is a member of some implicit instance at the point of the application.
40
40
41
41
As an example, consider an extension method `longestStrings` on `String` defined in a trait `StringSeqOps`.
42
42
@@ -48,15 +48,15 @@ trait StringSeqOps {
48
48
}
49
49
}
50
50
```
51
-
We can make the extension method available by defining evidence for`StringSeqOps`, like this:
51
+
We can make the extension method available by defining an implicit instance of`StringSeqOps`, like this:
52
52
```scala
53
53
instance ops1 of StringSeqOps
54
54
```
55
55
Then
56
56
```scala
57
57
List("here", "is", "a", "list").longestStrings
58
58
```
59
-
is legal everywhere `ops1` is available as evidence. Alternatively, we can define `longestStrings` as a member of a normal object. But then the method has to be brought into scope to be usable as an extension method.
59
+
is legal everywhere `ops1` is available as an implicit. Alternatively, we can define `longestStrings` as a member of a normal object. But then the method has to be brought into scope to be usable as an extension method.
60
60
61
61
```scala
62
62
objectops2extendsStringSeqOps
@@ -69,32 +69,32 @@ Assume a selection `e.m[Ts]` where `m` is not a member of `e`, where the type ar
69
69
and where `T` is the expected type. The following two rewritings are tried in order:
70
70
71
71
1. The selection is rewritten to `m[Ts](e)`.
72
-
2. If the first rewriting does not typecheck with expected type `T`, and there is evidence`i`
73
-
in either the current scope or in the evidence scope of `T`, and `i` defines an extension
72
+
2. If the first rewriting does not typecheck with expected type `T`, and there is an implicit`i`
73
+
in either the current scope or in the implicit scope of `T`, and `i` defines an extension
74
74
method named `m`, then selection is expanded to `i.m[Ts](e)`.
75
75
This second rewriting is attempted at the time where the compiler also tries an implicit conversion
76
76
from `T` to a type containing `m`. If there is more than one way of rewriting, an ambiguity error results.
77
77
78
78
So `circle.circumference` translates to `CircleOps.circumference(circle)`, provided
79
-
`circle` has type `Circle` and `CircleOps` is an eligible evidence value (i.e. it is visible at the point of call or it is defined in the companion object of `Circle`).
79
+
`circle` has type `Circle` and `CircleOps` is an eligible implicit (i.e. it is visible at the point of call or it is defined in the companion object of `Circle`).
80
80
81
-
### Evidence for Extension Methods
81
+
### Implicit Instances for Extension Methods
82
82
83
-
Evidence that defines extension methods can also be defined without a `for` clause. E.g.,
83
+
Implicits that wrap extension methods can also be defined without an `of` clause. E.g.,
Copy file name to clipboardExpand all lines: docs/docs/reference/contextual-instance/inferable-by-name-parameters.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
layout: doc-page
3
-
title: "Implicit By-Name Parameters"
3
+
title: "Inferable By-Name Parameters"
4
4
---
5
5
6
6
Inferable by-name parameters can be used to avoid a divergent inferred expansion. Example:
@@ -42,7 +42,7 @@ The precise steps for constructing an inferable argument for a by-name parameter
42
42
43
43
1. This instance is not immediately available ascandidatefor argument inference (making it immediately available could result in a loop in the synthesized computation). But it becomes available in all nested contexts that look again for an inferred argument to a by-name parameter.
44
44
45
-
1. Ifthis search succeeds with expression `E`, and `E` contains references to the evidence `lv`, replace `E` by
45
+
1. Ifthis search succeeds with expression `E`, and `E` contains references to `lv`, replace `E` by
0 commit comments