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
We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Show` instances are _derived instances_.
28
28
29
29
## Exact mechanism
30
-
More formally, for a class/trait/object/enum `DerivingType[T_1, ..., T_N] derives TC` (if `DerivingType` does not take parameters, we define `N = 0`), a derived instance is created in `DerivingType`'s companion object (or `DerivingType` itself if it is an object)
30
+
More formally, for a class/trait/object/enum `DerivingType[T_1, ..., T_N] derives TC`, a derived instance is created in `DerivingType`'s companion object (or `DerivingType` itself if it is an object).
31
+
If `DerivingType` does not take parameters, we define `N = 0`.
31
32
32
-
What the derived instance looks like depends on the specifics of `DerivingType` and `TC`, first the arity of `TC`:
33
+
What the derived instance looks like depends on the specifics of `DerivingType` and `TC`, but the general shape is as follows:
34
+
```scala
35
+
given [...]:TC[ ... DerivingType[...] ... ] =TC.derived
36
+
```
37
+
38
+
The first condition is the arity of `TC`:
33
39
34
40
### `TC` takes 1 parameter
35
41
@@ -46,58 +52,60 @@ If `N == 0`, we understand the above to mean:
46
52
```scala
47
53
givenTC[DerivingType] =TC.derived
48
54
```
55
+
#### `F` and `DerivingType` have parameters of matching kind on the right
56
+
This section concers cases where you can pair arguments of `F` and `DerivingType` starting from the right such that they have the same kinds pairwise, and all arguments of `F` or `DerivingType` (or both) are used up.
57
+
We also add the requirement that `F` have at least one parameter.
58
+
59
+
The general shape will then be:
60
+
```scala
61
+
given [...]:TC[[...] =>DerivingType[...]] =TC.derived
62
+
```
63
+
Where of course `TC` and `DerivingType` are applied to types of the correct kind.
49
64
50
-
<!-- #### You can pair arguments of `F` and `DerivingType` starting from the right such that they have the same kinds pairwise, and all arguments of at least one of them are used up -->
51
-
#### `F` and `DerivingType` have their `m` rightmost arguments which have the same kind pairwise and `N >= 0`, `K > 0`, and `m == N` and/or `m == K`
65
+
To make this work, we split it into 3 cases:
52
66
53
67
The generated instance is then:
54
-
If `m == N == K`:
68
+
If `TC` and `DerivingType` take the same number of arguments (`N == K`):
given [T_1L, T_1R, ..., T_NL, T_NR]// every parameter of DerivingType twice
99
+
(usingCanEqual[U_1L, U_1R], ..., CanEqual[U_NL, U_NR]):// only parameters of Deriving type with kind *
100
+
CanEqual[DerivingType[T_1L, ..., T_NL], DerivingType[T_1R, ..., T_NR]] =// again, every parameter
84
101
CanEqual.derived
85
102
```
86
103
104
+
The bounds of `T_i`s are handled correctly, for example: `T_2 <: T_1` becomes `T_2L <: T_1L`.
105
+
87
106
### `TC` is not valid for automatic derivation
88
107
89
108
Throw some error.
90
-
<!--
91
-
More formally, for a class/trait/object/enum `DerivingType derives TC`, the following given instance is created in `DerivingType`'s companion object (or `DerivingType` itself if it is an object):
92
-
* if `DerivingType` doesn't have type parameters
93
-
```scala
94
-
given TC[DerivingType] = TC.derived
95
-
```
96
-
* if `DerivingType` has type parameters `[T_1, ..., T_N]`
0 commit comments