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/experimental/typeclasses.md
+6-1
Original file line number
Diff line number
Diff line change
@@ -220,14 +220,16 @@ So far, an unnamed context bound for a type parameter gets a synthesized fresh n
220
220
xs.foldLeft(A.unit)(_ `combine` _)
221
221
```
222
222
223
-
The use of a name like `A` above in two variants, both as a type name and as a term name is of course familiar to Scala programmers. We use the same convention for classes and companion objects. In retrospect, the idea of generalizing this to also cover type parameters is obvious. It is surprising that it was not brought up before.
223
+
In Scala we are already familiar with using one name for two related things where one version names a type and the other an associated value. For instance, we use that convention for classes and companion objects. In retrospect, the idea of generalizing this to also cover type parameters is obvious. It is surprising that it was not brought up before.
224
224
225
225
**Proposed Rules**
226
226
227
227
1. The generated evidence parameter for a context bound `A : C as a` has name `a`
228
228
2. The generated evidence for a context bound `A : C` without an `as` binding has name `A` (seen as a term name). So, `A : C` is equivalent to `A : C as A`.
229
229
3. If there are multiple context bounds for a type parameter, as in `A : {C_1, ..., C_n}`, the generated evidence parameter for every context bound `C_i` has a fresh synthesized name, unless the context bound carries an `as` clause, in which case rule (1) applies.
230
230
231
+
TODO: Present context bound proxy concept.
232
+
231
233
The default naming convention reduces the need for named context bounds. But named context bounds are still essential, for at least two reasons:
232
234
233
235
- They are needed to give names to multiple context bounds.
@@ -357,6 +359,8 @@ given Int is Monoid:
357
359
extension (x: Int) defcombine(y: Int) = x + y
358
360
defunit=0
359
361
```
362
+
Here, the second given can be read as if `A` is an `Ord` then `List[A]` is also an`Ord`. Or: for all `A: Ord`, `List[A]` is `Ord`. The arrow can be seen as an implication, note also the analogy to pattern matching syntax.
363
+
360
364
If explicit names are desired, we add them with `as` clauses:
361
365
```scala
362
366
givenString is OrdasintOrd:
@@ -558,6 +562,7 @@ Here are some standard type classes, which were mostly already introduced at the
558
562
defminimum[T:Ord](xs: List[T]) =
559
563
maximum(xs)(using descending)
560
564
```
565
+
The `Reader` type is a bit hairy. It is a type class (written in the parameterized syntax) where we fix a context `Ctx` and then let `Reader` be the polymorphic function type over `X` that takes a context `Ctx` and returns an `X`. Type classes like this are commonly used in monadic effect systems.
0 commit comments