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
Besides for `enums`, typeclasses can also be derived for other sets of classes and objects that form an algebraic data type. These are:
22
+
Besides for enums, typeclasses can also be derived for other sets of classes and objects that form an algebraic data type. These are:
23
23
24
24
- individual case classes or case objects
25
25
- sealed classes or traits that have only case classes and case objects as children.
@@ -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 a delegate for `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``(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]`.
This creates a delegate `ctx` of type `ExecutionContext` that resolves to the right hand side `new ForkJoinPool()`.
56
-
The first time a delegate for `ExecutionContext` is demanded, a new `ForkJoinPool` is created, which is then
57
-
returned for this and all subsequent accesses to `ctx`.
55
+
This creates a delegate `global` of type `ExecutionContext` that resolves to the right hand side `new ForkJoinPool()`.
56
+
The first time `global` is accessed, a new `ForkJoinPool` is created, which is then
57
+
returned for this and all subsequent accesses to `global`.
58
58
59
59
Alias delegates can be anonymous, e.g.
60
60
```scala
@@ -64,7 +64,7 @@ An alias delegate can have type and context parameters just like any other deleg
64
64
65
65
## Delegate Creation
66
66
67
-
A delegate without type parameters or given clause is created on-demand, the first time it is accessed. No attempt is made to ensure safe publication, which means that different threads might create different delegates for the same `delegate` clause. If a `delegate` clause has type parameters or a given clause, a fresh delegate is created for each reference.
67
+
A delegate without type parameters or given clause is created on-demand, the first time it is accessed. It is not required to ensure safe publication, which means that different threads might create different delegates for the same `delegate` clause. If a `delegate` clause has type parameters or a given clause, a fresh delegate is created for each reference.
3. Alias delegates map to implicit methods. If the delegates has neither typeparameters nor a givenclause, the result of creating an instance is cached in a variable. If in addition the right hand side is pure and cheap to compute, a simple `val` can be used instead. E.g.,
31
+
3. Alias delegates map to implicit methods. If the delegate has neither typeparameters nor a givenclause, the result of creating an instance is cached in a variable. If in addition the right hand side is pure and cheap to compute, a simple `val` can be used instead. E.g.,
Copy file name to clipboardExpand all lines: docs/docs/reference/contextual-implicit/context-bounds.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,11 +5,11 @@ title: "Context Bounds"
5
5
6
6
## Context Bounds
7
7
8
-
A context bound is a shorthand for expressing a common pattern of an inferable parameter that depends on a type parameter. Using a context bound, the `maximum` function of the last section can be written like this:
8
+
A context bound is a shorthand for expressing a common pattern of an implicit parameter that depends on a type parameter. Using a context bound, the `maximum` function of the last section can be written like this:
A bound like `: Ord` on a type parameter `T` of a method or class indicates an inferable parameter `given Ord[T]`. The inferable parameter(s) generated from context bounds come last in the definition of the containing method or class. E.g.,
12
+
A bound like `: Ord` on a type parameter `T` of a method or class is equivalent to a given clause `given Ord[T]`. The implicit parameter(s) generated from context bounds come last in the definition of the containing method or class. E.g.,
Besides for `enums`, typeclasses can also be derived for other sets of classes and objects that form an algebraic data type. These are:
22
+
Besides for enums, typeclasses can also be derived for other sets of classes and objects that form an algebraic data type. These are:
23
23
24
24
- individual case classes or case objects
25
25
- sealed classes or traits that have only case classes and case objects as children.
@@ -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. Implicits for `Generic` are generated automatically for any type that derives a typeclass with a `derived`
45
+
That is, the `derived` method takes an implicit parameter of type `Generic` that determines the _shape_ of the deriving type `T` and it computes the typeclass implementation according to that shape. Implicits for `Generic` are 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
@@ -141,15 +141,15 @@ abstract class Generic[T] {
141
141
```
142
142
It defines the `Shape` type for the ADT `T`, as well as two methods that map between a
143
143
type `T` and a generic representation of `T`, which we call a `Mirror`:
144
-
The `reflect` method maps an instance value of the ADT `T` to its mirror whereas
144
+
The `reflect` method maps an instance of the ADT `T` to its mirror whereas
145
145
the `reify` method goes the other way. There's also a `common` method that returns
146
146
a value of type `GenericClass` which contains information that is the same for all
147
147
instances of a class (right now, this consists of the runtime `Class` value and
148
148
the names of the cases and their parameters).
149
149
150
150
### Mirrors
151
151
152
-
A mirror is a generic representation of an instance value of an ADT. `Mirror` objects have three components:
152
+
A mirror is a generic representation of an instance of an ADT. `Mirror` objects have three components:
153
153
154
154
-`adtClass: GenericClass`: The representation of the ADT class
155
155
-`ordinal: Int`: The ordinal number of the case among all cases of the ADT, starting from 0
@@ -214,8 +214,8 @@ trait Eql[T] {
214
214
defeql(x: T, y: T):Boolean
215
215
}
216
216
```
217
-
We need to implement a method `Eql.derived` that produces an instance of`Eql[T]` provided
218
-
there exists an implicit of type `Generic[T]`. Here's a possible solution:
217
+
We need to implement a method `Eql.derived` that produces an implicit value of type`Eql[T]` provided
218
+
there exists an implicit value of type `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= {
@@ -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
-
implicit [T] given (elemEq: Eql[T]) forEql[Tree[T]] {
317
+
implicit [T] forEql[Tree[T]] given (elemEq: Eql[T]) {
318
318
defeql(x: Tree[T], y: Tree[T]):Boolean= {
319
319
valev= the[Generic[Tree[T]]]
320
320
valmx= ev.reflect(x)
@@ -342,7 +342,7 @@ To do this, simply define an instance with the `derived` method of the typeclass
0 commit comments