Skip to content

Commit eebc7f2

Browse files
committed
Update derivation.md
1 parent 67468d3 commit eebc7f2

File tree

1 file changed

+15
-23
lines changed

1 file changed

+15
-23
lines changed

docs/_docs/reference/contextual/derivation.md

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/derivation.ht
77
Type class derivation is a way to automatically generate given instances for type classes which satisfy some simple
88
conditions. A type class in this sense is any trait or class with a type parameter determining the type being operated
99
on. Common examples are `Eq`, `Ordering`, or `Show`. For example, given the following `Tree` algebraic data type
10-
(ADT),
10+
(ADT):
1111

1212
```scala
1313
enum Tree[T] derives Eq, Ordering, Show:
@@ -16,7 +16,7 @@ enum Tree[T] derives Eq, Ordering, Show:
1616
```
1717

1818
The `derives` clause generates the following given instances for the `Eq`, `Ordering` and `Show` type classes in the
19-
companion object of `Tree`,
19+
companion object of `Tree`:
2020

2121
```scala
2222
given [T: Eq] : Eq[Tree[T]] = Eq.derived
@@ -26,11 +26,21 @@ given [T: Show] : Show[Tree[T]] = Show.derived
2626

2727
We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Show` instances are _derived instances_.
2828

29-
## Types supporting `derives` clauses
29+
**Note:** The access to `derived` above is a normal access, therefore if there are multiple definitions of `derived` in the type class, overloading resolution applies.
30+
31+
**Note:** `derived` can be used manually, this is useful when you do not have control over the definition. For example we can implement an `Ordering` for `Option`s like so:
32+
33+
```scala
34+
given [T: Ordering]: Ordering[Option[T]] = Ordering.derived
35+
```
36+
37+
It is discouraged to directly refer to the `derived` member if you can use a `derives` clause instead.
3038

3139
All data types can have a `derives` clause. This document focuses primarily on data types which also have a given instance
3240
of the `Mirror` type class available.
3341

42+
## `Mirror`
43+
3444
`Mirror` type class instances provide information at the type level about the components and labelling of the type.
3545
They also provide minimal term level infrastructure to allow higher level libraries to provide comprehensive
3646
derivation support.
@@ -158,15 +168,11 @@ Note the following properties of `Mirror` types,
158168
+ The methods `ordinal` and `fromProduct` are defined in terms of `MirroredMonoType` which is the type of kind-`*`
159169
which is obtained from `MirroredType` by wildcarding its type parameters.
160170

161-
## Type classes supporting automatic deriving
171+
### Implementing `derived` with `Mirror`
162172

163-
A trait or class can appear in a `derives` clause if its companion object defines a method named `derived`. The
164-
signature and implementation of a `derived` method for a type class `TC[_]` are arbitrary but it is typically of the
165-
following form,
173+
As seen before, the signature and implementation of a `derived` method for a type class `TC[_]` are arbitrary, but we expect it to typically be of the following form:
166174

167175
```scala
168-
import scala.deriving.Mirror
169-
170176
inline def derived[T](using Mirror.Of[T]): TC[T] = ...
171177
```
172178

@@ -360,20 +366,6 @@ The framework described here enables all three of these approaches without manda
360366
For a brief discussion on how to use macros to write a type class `derived`
361367
method please read more at [How to write a type class `derived` method using macros](./derivation-macro.md).
362368

363-
## Deriving instances elsewhere
364-
365-
Sometimes one would like to derive a type class instance for an ADT after the ADT is defined, without being able to
366-
change the code of the ADT itself. To do this, simply define an instance using the `derived` method of the type class
367-
as right-hand side. E.g, to implement `Ordering` for `Option` define,
368-
369-
```scala
370-
given [T: Ordering]: Ordering[Option[T]] = Ordering.derived
371-
```
372-
373-
Assuming the `Ordering.derived` method has a context parameter of type `Mirror[T]` it will be satisfied by the
374-
compiler generated `Mirror` instance for `Option` and the derivation of the instance will be expanded on the right
375-
hand side of this definition in the same way as an instance defined in ADT companion objects.
376-
377369
## Syntax
378370

379371
```

0 commit comments

Comments
 (0)