Skip to content

Commit 45c25ea

Browse files
OlivierBlanvillainodersky
authored andcommitted
Fix typos in documentation
1 parent 2e2f33c commit 45c25ea

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

docs/docs/reference/derivation.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class Mirror(val adtClass: GenericClass, val ordinal: Int, val elems: Product) {
176176
def caseLabel: String = adtClass.label(ordinal)(0)
177177

178178
/** The label of the `n`'th element of the case reflected by this mirror */
179-
def elementLabel(n: Int) = adtClass.label(ordinal)(n + 1)
179+
def elementLabel(n: Int): String = adtClass.label(ordinal)(n + 1)
180180
}
181181
```
182182

@@ -207,6 +207,7 @@ class GenericClass(val runtimeClass: Class[_], labelsStr: String) {
207207
* Each row of the array contains a case label, followed by the labels of the elements of that case.
208208
*/
209209
val label: Array[Array[String]] = ...
210+
}
210211
```
211212

212213
The class provides four overloaded methods to create mirrors. The first of these is invoked by the `reify` method that maps an ADT instance to its mirror. It simply passes the
@@ -216,7 +217,7 @@ a mirror over that array, and finally uses the `reify` method in `Reflected` to
216217
### How to Write Generic Typeclasses
217218

218219
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.
219-
The implementation of these methods typically uses three new typelevel constructs in Dotty: inline methods, inline matches and implicit matches. As an example, here is one possible implementation of a generic `Eq` type class, with explanations. Let's assume `Eq` is defined by the following trait:
220+
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 `Eq` type class, with explanations. Let's assume `Eq` is defined by the following trait:
220221
```scala
221222
trait Eq[T] {
222223
def eql(x: T, y: T): Boolean
@@ -239,11 +240,11 @@ there exists evidence of type `Generic[T]`. Here's a possible solution:
239240
}
240241
}
241242
```
242-
The implementation of the inline method `derived` creates an instance of `Eq[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
243+
The implementation of the inline method `derived` creates an instance of `Eq[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
243244
`(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.
244245

245246
1. Map the compared values `x` and `y` to their mirrors using the `reflect` method of the implicitly passed `Generic` evidence `(1)`, `(2)`.
246-
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, buy 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.
247+
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.
247248
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]`.
248249
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]`.
249250

@@ -260,7 +261,7 @@ Here is a possible implementation of `eqlCases`:
260261
throw new MatchError(mx.ordinal) // (9)
261262
}
262263
```
263-
The inline method `eqlCases` takes as type arguments the alternatives of the ADT that remain to be tested. It takes as value arguments mirrors of the two instances `x` and `y` to be compared and an integer `n` that indicates the ordinal number of the case that is tested next. Its produces an expression that compares these two values.
264+
The inline method `eqlCases` takes as type arguments the alternatives of the ADT that remain to be tested. It takes as value arguments mirrors of the two instances `x` and `y` to be compared and an integer `n` that indicates the ordinal number of the case that is tested next. It produces an expression that compares these two values.
264265

265266
If the list of alternatives `Alts` consists of a case of type `Case[_, elems]`, possibly followed by further cases in `alts1`, we generate the following code:
266267

@@ -291,7 +292,7 @@ implementation:
291292
true // (14)
292293
}
293294
```
294-
`eqlElems` takes as arguments the two mirrors of the elements to compare and a compile-time index `n`, indicating the index of the next element to test. It is defined in terms of an another compile-time match, this time over the tuple type `Elems` of all element types that remain to be tested. If that type is
295+
`eqlElems` takes as arguments the two mirrors of the elements to compare and a compile-time index `n`, indicating the index of the next element to test. It is defined in terms of another compile-time match, this time over the tuple type `Elems` of all element types that remain to be tested. If that type is
295296
non-empty, say of form `elem *: elems1`, the following code is produced:
296297

297298
1. Access the `n`'th elements of both mirrors and cast them to the current element type `elem`
@@ -314,10 +315,10 @@ The last, and in a sense most interesting part of the derivation is the comparis
314315
}
315316
```
316317
`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 `inline match` that tries to find an implicit instance of `Eq[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
317-
this signals a compilation error: the user tried a generic derivation of `Eq` for a class with an element type that does not support an `Eq` instance itself. The error is signalled by
318+
this signals a compilation error: the user tried a generic derivation of `Eq` for a class with an element type that does not support an `Eq` instance itself. The error is signaled by
318319
calling the `error` method defined in `scala.compiletime`.
319320

320-
**Note:** At the moment our error diagnostics for meta programming 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.
321+
**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.
321322

322323
**Example:** Here is a slightly polished and compacted version of the code that's generated by inline expansion for the derived `Eq` instance of class `Tree`.
323324

@@ -346,7 +347,7 @@ One important difference between this approach and Scala-2 typeclass derivation
346347
### Derived Instances Elsewhere
347348

348349
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.
349-
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:
350+
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:
350351
```scala
351352
implicit def myOptionOrdering[T: Ordering]: Ordering[Option[T]] = Ordering.derived
352353
```
@@ -388,4 +389,4 @@ are correctly written these casts will never fail.
388389
It could make sense to explore a higher-level framework that encapsulates all casts
389390
in the framework. This could give more guidance to the typeclass implementer.
390391
It also seems quite possible to put such a framework on top of the lower-level
391-
mechanisms presented here.
392+
mechanisms presented here.

0 commit comments

Comments
 (0)