Skip to content

Commit 2c756b1

Browse files
authored
Make code example self-contained (#2732)
1 parent 0441525 commit 2c756b1

File tree

1 file changed

+72
-9
lines changed

1 file changed

+72
-9
lines changed

_overviews/scala3-book/ca-context-bounds.md

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,108 @@ previous-page: ca-given-using-clauses
88
next-page: ca-given-imports
99
---
1010

11-
In many situations the name of a [context parameter]({% link _overviews/scala3-book/ca-given-using-clauses.md %}#using-clauses) doesn’t have to be mentioned explicitly, since it’s only used by the compiler in synthesized arguments for other context parameters.
11+
In many situations the name of a [context parameter]({% link _overviews/scala3-book/ca-given-using-clauses.md %}#using-clauses) does not have to be mentioned explicitly, since it is only used by the compiler in synthesized arguments for other context parameters.
1212
In that case you don’t have to define a parameter name, and can just provide the parameter type.
1313

1414

1515
## Background
1616

17-
For example, this `maximum` method takes a _context parameter_ of type `Ord`, only to pass it on as an argument to `max`:
17+
For example, consider a method `maxElement` that returns the maximum value in a collection:
1818

1919
{% tabs context-bounds-max-named-param class=tabs-scala-version %}
2020

2121
{% tab 'Scala 2' %}
2222
```scala
23-
def maximum[A](xs: List[A])(implicit ord: Ord[A]): A =
24-
xs.reduceLeft(max(ord))
23+
def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
24+
as.reduceLeft(max(_, _)(ord))
2525
```
2626
{% endtab %}
2727

2828
{% tab 'Scala 3' %}
2929
```scala
30-
def maximum[A](xs: List[A])(using ord: Ord[A]): A =
31-
xs.reduceLeft(max(using ord))
30+
def maxElement[A](as: List[A])(using ord: Ord[A]): A =
31+
as.reduceLeft(max(_, _)(using ord))
3232
```
3333
{% endtab %}
3434

3535
{% endtabs %}
3636

37+
The method `maxElement` takes a _context parameter_ of type `Ord[A]` only to pass it on as an argument to the method
38+
`max`.
39+
40+
For the sake of completeness, here are the definitions of `max` and `Ord` (note that in practice we would use the
41+
existing method `max` on `List`, but we made up this example for illustration purpose):
42+
43+
{% tabs context-bounds-max-ord class=tabs-scala-version %}
44+
45+
{% tab 'Scala 2' %}
46+
```scala
47+
/** Defines how to compare values of type `A` */
48+
trait Ord[A] {
49+
def greaterThan(a1: A, a2: A): Boolean
50+
}
51+
52+
/** Returns the maximum of two values */
53+
def max[A](a1: A, a2: A)(implicit ord: Ord[A]): A =
54+
if (ord.greaterThan(a1, a2)) a1 else a2
55+
```
56+
{% endtab %}
57+
58+
{% tab 'Scala 3' %}
59+
```scala
60+
/** Defines how to compare values of type `A` */
61+
trait Ord[A]:
62+
def greaterThan(a1: A, a2: A): Boolean
63+
64+
/** Returns the maximum of two values */
65+
def max[A](a1: A, a2: A)(using ord: Ord[A]): A =
66+
if ord.greaterThan(a1, a2) then a1 else a2
67+
```
68+
{% endtab %}
69+
70+
{% endtabs %}
71+
72+
Note that the method `max` takes a context parameter of type `Ord[A]`, like the method `maxElement`.
73+
74+
## Omitting context arguments
75+
76+
Since `ord` is a context parameter in the method `max`, the compiler can supply it for us in the implementation of `maxElement`,
77+
when we call the method `max`:
78+
79+
{% tabs context-bounds-context class=tabs-scala-version %}
80+
81+
{% tab 'Scala 2' %}
82+
```scala
83+
def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
84+
as.reduceLeft(max(_, _))
85+
```
86+
{% endtab %}
87+
88+
{% tab 'Scala 3' %}
89+
```scala
90+
def maxElement[A](as: List[A])(using Ord[A]): A =
91+
as.reduceLeft(max(_, _))
92+
```
93+
94+
Note that, because we don’t need to explicitly pass it to the method `max`, we can leave out its name in the definition
95+
of the method `maxElement`. This is an _anonymous context parameter_.
96+
{% endtab %}
97+
98+
{% endtabs %}
99+
37100
## Context bounds
38101

39102
Given that background, a _context bound_ is a shorthand syntax for expressing the pattern of, “a context parameter applied to a type parameter.”
40103

41-
Using a context bound, the `maximum` method can be written like this:
104+
Using a context bound, the `maxElement` method can be written like this:
42105

43106
{% tabs context-bounds-max-rewritten %}
44107

45108
{% tab 'Scala 2 and 3' %}
46109

47110
```scala
48-
def maximum[A: Ord](xs: List[A]): A =
49-
xs.reduceLeft(max)
111+
def maxElement[A: Ord](as: List[A]): A =
112+
as.reduceLeft(max(_, _))
50113
```
51114

52115
{% endtab %}

0 commit comments

Comments
 (0)