Skip to content

Commit a4064be

Browse files
BersierKordyjan
authored andcommitted
Update derivation.md
Attempted small grammar improvements [Cherry-picked ec42994]
1 parent 4d20469 commit a4064be

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

Diff for: docs/_docs/reference/contextual/derivation.md

+21-21
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ given TC[DerivingType] = TC.derived
104104
// simplified form of:
105105
given TC[ [A_1, ..., A_K] =>> DerivingType[A_1, ..., A_K] ] = TC.derived
106106
```
107-
If `DerivingType` takes less arguments than `F` (`N < K`), we use only the rightmost parameters from the type lambda:
107+
If `DerivingType` takes fewer arguments than `F` (`N < K`), we use only the rightmost parameters from the type lambda:
108108
```scala
109109
given TC[ [A_1, ..., A_K] =>> DerivingType[A_(K-N+1), ..., A_K] ] = TC.derived
110110

111111
// if DerivingType takes no arguments (N == 0), the above simplifies to:
112112
given TC[ [A_1, ..., A_K] =>> DerivingType ] = TC.derived
113113
```
114114

115-
If `F` takes less arguments than `DerivingType` (`K < N`), we fill in the remaining leftmost slots with type parameters of the given:
115+
If `F` takes fewer arguments than `DerivingType` (`K < N`), we fill in the remaining leftmost slots with type parameters of the given:
116116
```scala
117117
given [T_1, ... T_(N-K)]: TC[[A_1, ..., A_K] =>> DerivingType[T_1, ... T_(N-K), A_1, ..., A_K]] = TC.derived
118118
```
@@ -158,7 +158,7 @@ of the `Mirror` type class available.
158158
## `Mirror`
159159

160160
`scala.deriving.Mirror` type class instances provide information at the type level about the components and labelling of the type.
161-
They also provide minimal term level infrastructure to allow higher level libraries to provide comprehensive
161+
They also provide minimal term-level infrastructure to allow higher-level libraries to provide comprehensive
162162
derivation support.
163163

164164
Instances of the `Mirror` type class are generated automatically by the compiler
@@ -269,14 +269,14 @@ No given instance of type deriving.Mirror.Of[A] was found for parameter x of met
269269
Note the following properties of `Mirror` types,
270270

271271
+ Properties are encoded using types rather than terms. This means that they have no runtime footprint unless used and
272-
also that they are a compile time feature for use with Scala 3's metaprogramming facilities.
272+
also that they are a compile-time feature for use with Scala 3's metaprogramming facilities.
273273
+ There is no restriction against the mirrored type being a local or inner class.
274274
+ The kinds of `MirroredType` and `MirroredElemTypes` match the kind of the data type the mirror is an instance for.
275275
This allows `Mirror`s to support ADTs of all kinds.
276276
+ There is no distinct representation type for sums or products (ie. there is no `HList` or `Coproduct` type as in
277277
Scala 2 versions of Shapeless). Instead the collection of child types of a data type is represented by an ordinary,
278278
possibly parameterized, tuple type. Scala 3's metaprogramming facilities can be used to work with these tuple types
279-
as-is, and higher level libraries can be built on top of them.
279+
as-is, and higher-level libraries can be built on top of them.
280280
+ For both product and sum types, the elements of `MirroredElemTypes` are arranged in definition order (i.e. `Branch[T]`
281281
precedes `Leaf[T]` in `MirroredElemTypes` for `Tree` because `Branch` is defined before `Leaf` in the source file).
282282
This means that `Mirror.Sum` differs in this respect from Shapeless's generic representation for ADTs in Scala 2,
@@ -303,16 +303,16 @@ has a context `Mirror` parameter, or not at all (e.g. they might use some comple
303303
instance using Scala 3 macros or runtime reflection). We expect that (direct or indirect) `Mirror` based implementations
304304
will be the most common and that is what this document emphasises.
305305

306-
Type class authors will most likely use higher level derivation or generic programming libraries to implement
307-
`derived` methods. An example of how a `derived` method might be implemented using _only_ the low level facilities
306+
Type class authors will most likely use higher-level derivation or generic programming libraries to implement
307+
`derived` methods. An example of how a `derived` method might be implemented using _only_ the low-level facilities
308308
described above and Scala 3's general metaprogramming features is provided below. It is not anticipated that type class
309309
authors would normally implement a `derived` method in this way, however this walkthrough can be taken as a guide for
310-
authors of the higher level derivation libraries that we expect typical type class authors will use (for a fully
310+
authors of the higher-level derivation libraries that we expect typical type class authors will use (for a fully
311311
worked out example of such a library, see [Shapeless 3](https://github.com/milessabin/shapeless/tree/shapeless-3)).
312312

313-
## How to write a type class `derived` method using low level mechanisms
313+
## How to write a type class `derived` method using low-level mechanisms
314314

315-
The low-level method we will use to implement a type class `derived` method in this example exploits three new type-level constructs in Scala 3: inline methods, inline matches, and implicit searches via `summonInline` or `summonFrom`.
315+
The low-level technique we will use to implement a type class `derived` method in this example exploits three new type-level constructs in Scala 3: inline methods, inline matches, and implicit searches via `summonInline` or `summonFrom`.
316316
Given this definition of the `Eq` type class,
317317

318318
```scala
@@ -335,13 +335,13 @@ inline def derived[T](using m: Mirror.Of[T]): Eq[T] =
335335
```
336336

337337
Note that `derived` is defined as an `inline def`.
338-
This means that the method will be inlined at all call sites (for instance the compiler generated instance definitions in the companion objects of ADTs which have a `deriving Eq` clause).
338+
This means that the method will be inlined at all call sites (for instance the compiler-generated instance definitions in the companion objects of ADTs which have a `deriving Eq` clause).
339339

340340
> Inlining of complex code is potentially expensive if overused (meaning slower compile times) so we should be careful to limit how many times `derived` is called for the same type.
341-
> For example, when computing an instance for a sum type, it may be necessary to call `derived` recursively to compute an instance for a one of its child cases.
341+
> For example, when computing an instance for a sum type, it may be necessary to call `derived` recursively to compute an instance for each one of its child cases.
342342
> That child case may in turn be a product type, that declares a field referring back to the parent sum type.
343343
> To compute the instance for this field, we should not call `derived` recursively, but instead summon from the context.
344-
> Typically the found given instance will be the root given instance that initially called `derived`.
344+
> Typically, the found given instance will be the root given instance that initially called `derived`.
345345
346346
The body of `derived` (1) first materializes the `Eq` instances for all the child types of type the instance is being derived for.
347347
This is either all the branches of a sum type or all the fields of a product type.
@@ -380,7 +380,7 @@ def eqSum[T](s: Mirror.SumOf[T], elems: => List[Eq[?]]): Eq[T] =
380380
(s.ordinal(y) == ordx) && check(x, y, elems(ordx)) // (4)
381381
```
382382

383-
In the product case, `eqProduct` we test the runtime values of the arguments to `eqv` for equality as products based on the `Eq` instances for the fields of the data type (5),
383+
In the product case, `eqProduct`, we test the runtime values of the arguments to `eqv` for equality as products based on the `Eq` instances for the fields of the data type (5),
384384

385385
```scala
386386
import scala.deriving.Mirror
@@ -486,7 +486,7 @@ Alternative approaches can be taken to the way that `derived` methods can be def
486486
inlined variants using Scala 3 macros, whilst being more involved for type class authors to write than the example
487487
above, can produce code for type classes like `Eq` which eliminate all the abstraction artefacts (eg. the `Lists` of
488488
child instances in the above) and generate code which is indistinguishable from what a programmer might write by hand.
489-
As a third example, using a higher level library such as Shapeless the type class author could define an equivalent
489+
As a third example, using a higher-level library such as Shapeless, the type class author could define an equivalent
490490
`derived` method as,
491491

492492
```scala
@@ -508,7 +508,7 @@ inline def derived[A](using gen: K0.Generic[A]): Eq[A] =
508508
The framework described here enables all three of these approaches without mandating any of them.
509509

510510
For a brief discussion on how to use macros to write a type class `derived`
511-
method please read more at [How to write a type class `derived` method using macros](./derivation-macro.md).
511+
method, please read more at [How to write a type class `derived` method using macros](./derivation-macro.md).
512512

513513
## Syntax
514514

@@ -539,22 +539,22 @@ This type class derivation framework is intentionally very small and low-level.
539539
infrastructure in compiler-generated `Mirror` instances,
540540

541541
+ type members encoding properties of the mirrored types.
542-
+ a minimal value level mechanism for working generically with terms of the mirrored types.
542+
+ a minimal value-level mechanism for working generically with terms of the mirrored types.
543543

544544
The `Mirror` infrastructure can be seen as an extension of the existing `Product` infrastructure for case classes:
545-
typically `Mirror` types will be implemented by the ADTs companion object, hence the type members and the `ordinal` or
545+
typically, `Mirror` types will be implemented by the ADTs companion object, hence the type members and the `ordinal` or
546546
`fromProduct` methods will be members of that object. The primary motivation for this design decision, and the
547547
decision to encode properties via types rather than terms was to keep the bytecode and runtime footprint of the
548548
feature small enough to make it possible to provide `Mirror` instances _unconditionally_.
549549

550-
Whilst `Mirrors` encode properties precisely via type members, the value level `ordinal` and `fromProduct` are
550+
Whilst `Mirrors` encode properties precisely via type members, the value-level `ordinal` and `fromProduct` are
551551
somewhat weakly typed (because they are defined in terms of `MirroredMonoType`) just like the members of `Product`.
552552
This means that code for generic type classes has to ensure that type exploration and value selection proceed in
553553
lockstep and it has to assert this conformance in some places using casts. If generic type classes are correctly
554554
written these casts will never fail.
555555

556-
As mentioned, however, the compiler-provided mechanism is intentionally very low level and it is anticipated that
557-
higher level type class derivation and generic programming libraries will build on this and Scala 3's other
556+
As mentioned, however, the compiler-provided mechanism is intentionally very low-level and it is anticipated that
557+
higher-level type class derivation and generic programming libraries will build on this and Scala 3's other
558558
metaprogramming facilities to hide these low-level details from type class authors and general users. Type class
559559
derivation in the style of both Shapeless and Magnolia are possible (a prototype of Shapeless 3, which combines
560560
aspects of both Shapeless 2 and Magnolia has been developed alongside this language feature) as is a more aggressively

0 commit comments

Comments
 (0)