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/contextual/context-bounds.md
+2-2Lines changed: 2 additions & 2 deletions
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 a context 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 indicates a context parameter `given Ord[T]`. The context parameter(s) generated from context bounds come last in the definition of the containing method or class. E.g.,
Copy file name to clipboardExpand all lines: docs/docs/reference/contextual/derivation.md
+16-16Lines changed: 16 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@ layout: doc-page
3
3
title: Typeclass Derivation
4
4
---
5
5
6
-
Typeclass derivation is a way to generate instances of certain type classes automatically or with minimal code hints. A type class in this sense is any trait or class with a type parameter that describes the type being operated on. Commonly used examples are `Eql`, `Ordering`, `Show`, or `Pickling`. Example:
6
+
Typeclass derivation is a way to generate implied instances of certain type classes automatically or with minimal code hints. A type class in this sense is any trait or class with a type parameter that describes the type being operated on. Commonly used examples are `Eql`, `Ordering`, `Show`, or `Pickling`. Example:
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. An implied `Generic` instance is generated automatically for any type that derives a typeclass with a `derived`
45
+
That is, the `derived` method takes a context parameter of type `Generic` that determines the _shape_ of the deriving type `T` and it computes the typeclass implementation according to that shape. An implied `Generic` instance 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
@@ -142,15 +142,15 @@ abstract class Generic[T] {
142
142
```
143
143
It defines the `Shape` type for the ADT `T`, as well as two methods that map between a
144
144
type `T` and a generic representation of `T`, which we call a `Mirror`:
145
-
The `reflect` method maps an instance value of the ADT `T` to its mirror whereas
145
+
The `reflect` method maps an instance of the ADT `T` to its mirror whereas
146
146
the `reify` method goes the other way. There's also a `common` method that returns
147
147
a value of type `GenericClass` which contains information that is the same for all
148
148
instances of a class (right now, this consists of the runtime `Class` value and
149
149
the names of the cases and their parameters).
150
150
151
151
### Mirrors
152
152
153
-
A mirror is a generic representation of an instance value of an ADT. `Mirror` objects have three components:
153
+
A mirror is a generic representation of an instance of an ADT. `Mirror` objects have three components:
154
154
155
155
-`adtClass: GenericClass`: The representation of the ADT class
156
156
-`ordinal: Int`: The ordinal number of the case among all cases of the ADT, starting from 0
@@ -208,15 +208,15 @@ a mirror over that array, and finally uses the `reify` method in `Reflected` to
208
208
209
209
### How to Write Generic Typeclasses
210
210
211
-
Based on the machinery developed so far it becomes possible to define type classes generically. This means that the `derived` method will compute a type class instance for any ADT that has a`Generic` instance, recursively.
211
+
Based on the machinery developed so far it becomes possible to define type classes generically. This means that the `derived` method will compute a type class instance for any ADT that has an implied`Generic` instance, recursively.
212
212
The implementation of these methods typically uses three new type-level constructs in Dotty: inline methods, inline matches, and implicit matches. As an example, here is one possible implementation of a generic `Eql` type class, with explanations. Let's assume `Eql` is defined by the following trait:
213
213
```scala
214
214
traitEql[T] {
215
215
defeql(x: T, y: T):Boolean
216
216
}
217
217
```
218
-
We need to implement a method `Eql.derived` that produces an instance of`Eql[T]` provided
219
-
there exists evidence of type`Generic[T]`. Here's a possible solution:
218
+
We need to implement a method `Eql.derived` that produces an instance for`Eql[T]` provided
219
+
there exists an implied instance for`Generic[T]`. Here's a possible solution:
220
220
```scala
221
221
inlinedefderived[T] given (ev: Generic[T]):Eql[T] =newEql[T] {
222
222
defeql(x: T, y: T):Boolean= {
@@ -307,15 +307,15 @@ The last, and in a sense most interesting part of the derivation is the comparis
307
307
}
308
308
```
309
309
`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 `implicit match` that tries to find an implied 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
310
-
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
+
this signals a compilation error: the user tried a generic derivation of `Eql` for a class with an element type that does not have an `Eql` instance itself. The error is signaled by
311
311
calling the `error` method defined in `scala.compiletime`.
312
312
313
313
**Note:** At the moment our error diagnostics for metaprogramming does not support yet interpolated string arguments for the `scala.compiletime.error` method that is called in the second case above. As an alternative, one can simply leave off the second case, then a missing typeclass would result in a "failure to reduce match" error.
314
314
315
315
**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`.
316
316
317
317
```scala
318
-
implied [T] given (elemEq: Eql[T]) forEql[Tree[T]] {
318
+
implied [T] forEql[Tree[T]] given (elemEq: Eql[T]) {
319
319
defeql(x: Tree[T], y: Tree[T]):Boolean= {
320
320
valev= the[Generic[Tree[T]]]
321
321
valmx= ev.reflect(x)
@@ -336,14 +336,14 @@ implied [T] given (elemEq: Eql[T]) for Eql[Tree[T]] {
336
336
337
337
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 implied instance of `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.
338
338
339
-
### Derived Instances Elsewhere
339
+
### Deriving Instances Elsewhere
340
340
341
341
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.
342
342
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/import-implied.md
+9-9Lines changed: 9 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
layout: doc-page
3
-
title: "Implied Imports"
3
+
title: "Importing Implied Instances"
4
4
---
5
5
6
6
A special form of import is used to import implied instances. Example:
@@ -18,7 +18,7 @@ object B {
18
18
In the code above, the `import A._` clause of object `B` will import all members
19
19
of `A`_except_ the implied instance `tc`. Conversely, the second import `import implied A._` will import _only_ that implied instance.
20
20
21
-
Generally, a normal import clause brings all definitions except implied instances into scope whereas an `import implied` clause brings only implied instances into scope.
21
+
Generally, a normal import clause brings all members except implied instances into scope whereas an `import implied` clause brings only implied instances into scope.
22
22
23
23
There are two main benefits arising from these rules:
24
24
@@ -28,22 +28,22 @@ There are two main benefits arising from these rules:
28
28
instances can be anonymous, so the usual recourse of using named imports is not
29
29
practical.
30
30
31
-
### Relationship with Old-Style Implicits
31
+
### Migration
32
32
33
-
The rules of implied imports above have the consequence that a library
33
+
The rules for `import implied` above have the consequence that a library
34
34
would have to migrate in lockstep with all its users from old style implicits and
35
35
normal imports to implied instances and imports.
36
36
37
37
The following modifications avoid this hurdle to migration.
38
38
39
-
1. An implied import also brings old style implicits into scope. So, in Scala 3.0
40
-
an old-style implicit definition can be brought into scope either by a normal or
41
-
by an implied import.
39
+
1. An `import implied` also brings old style implicits into scope. So, in Scala 3.0
40
+
an old-style implicit definition can be brought into scope either by a normal import or
41
+
by an `import implied`.
42
42
43
-
2. In Scala 3.1, an old-style implicits accessed implicitly through a normal import
43
+
2. In Scala 3.1, old-style implicits accessed through a normal import
44
44
will give a deprecation warning.
45
45
46
-
3. In some version after 3.1, an old-style implicits accessed implicitly through a normal import
46
+
3. In some version after 3.1, an old-style implicit accessed through a normal import
47
47
will give a compiler error.
48
48
49
49
These rules mean that library users can use `import implied` to access old-style implicits in Scala 3.0,
0 commit comments