Skip to content

Commit 51994bb

Browse files
committed
Updated pages to be 'Scala 3 Only'
1 parent c5e795b commit 51994bb

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

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

+26
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ num: 61
77
previous-page: ca-given-using-clauses
88
next-page: ca-given-imports
99
---
10+
<span class="tag tag-inline">Scala 3 only</span>
1011

1112

1213
{% comment %}
@@ -22,29 +23,54 @@ In that case you don’t have to define a parameter name, and can just provide t
2223

2324
For example, this `maximum` method takes a _context parameter_ of type `Ord`, only to pass it on as an argument to `max`:
2425

26+
{% tabs context-bounds-max-named-param %}
27+
28+
{% tab 'Scala 3 Only' %}
29+
2530
```scala
2631
def maximum[A](xs: List[A])(using ord: Ord[A]): A =
2732
xs.reduceLeft(max(ord))
2833
```
2934

35+
{% endtab %}
36+
37+
{% endtabs %}
38+
3039
In that code the parameter name `ord` isn’t actually required; it can be passed on as an inferred argument to `max`, so you just state that `maximum` uses the type `Ord[A]` without giving it a name:
3140

41+
{% tabs context-bounds-no-param-name %}
42+
43+
{% tab 'Scala 3 Only' %}
44+
3245
```scala
3346
def maximum[A](xs: List[A])(using Ord[A]): A =
3447
xs.reduceLeft(max)
3548
```
3649

50+
{% endtab %}
51+
52+
{% endtabs %}
53+
3754

3855
## Context bounds
3956

4057
Given that background, a _context bound_ is a shorthand syntax for expressing the pattern of, “a context parameter that depends on a type parameter.”
4158

4259
Using a context bound, the `maximum` method can be written like this:
4360

61+
{% tabs context-bounds-max-rewritten %}
62+
63+
{% tab 'Scala 3 Only' %}
64+
4465
```scala
4566
def maximum[A: Ord](xs: List[A]): A = xs.reduceLeft(max)
4667
```
4768

69+
{% endtab %}
70+
71+
{% endtabs %}
72+
73+
4874
A bound like `: Ord` on a type parameter `A` of a method or class indicates a context parameter with `Ord[A]`.
4975

5076
For more information about context bounds, see the [“What are context bounds?”](https://docs.scala-lang.org/tutorials/FAQ/context-bounds.html) section of the Scala FAQ.

_overviews/scala3-book/ca-given-imports.md

+17
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ num: 62
77
previous-page: ca-context-bounds
88
next-page: ca-type-classes
99
---
10+
<span class="tag tag-inline">Scala 3 only</span>
1011

1112

1213
To make it more clear where givens in the current scope are coming from, a special form of the `import` statement is used to import `given` instances.
1314
The basic form is shown in this example:
1415

16+
{% tabs given-imports-basic-form %}
17+
18+
{% tab 'Scala 3 Only' %}
19+
1520
```scala
1621
object A:
1722
class TC
@@ -23,15 +28,27 @@ object B:
2328
import A.given // import the given instance
2429
```
2530

31+
{% endtab %}
32+
33+
{% endtabs %}
34+
2635
In this code the `import A.*` clause of object `B` imports all members of `A` *except* the `given` instance, `tc`.
2736
Conversely, the second import, `import A.given`, imports *only* that `given` instance.
2837
The two `import` clauses can also be merged into one:
2938

39+
{% tabs given-imports-merged %}
40+
41+
{% tab 'Scala 3 Only' %}
42+
3043
```scala
3144
object B:
3245
import A.{given, *}
3346
```
3447

48+
{% endtab %}
49+
50+
{% endtabs %}
51+
3552

3653
## Discussion
3754

_overviews/scala3-book/ca-multiversal-equality.md

+49
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ num: 64
77
previous-page: ca-type-classes
88
next-page: ca-implicit-conversions
99
---
10+
<span class="tag tag-inline">Scala 3 only</span>
1011

1112

1213
Previously, Scala had *universal equality*: Two values of any types could be compared with each other using `==` and `!=`.
@@ -44,6 +45,10 @@ d == c // false, but it compiles
4445
But with Scala 3 you can disable such comparisons.
4546
By (a) importing `scala.language.strictEquality` or (b) using the `-language:strictEquality` compiler flag, this comparison no longer compiles:
4647

48+
{% tabs multiversal-equality-strictEquality %}
49+
50+
{% tab 'Scala 3 Only' %}
51+
4752
```scala
4853
import scala.language.strictEquality
4954

@@ -55,25 +60,45 @@ println(rover == fido) // compiler error
5560
// Values of types Dog and Dog cannot be compared with == or !=
5661
```
5762

63+
{% endtab %}
64+
65+
{% endtabs %}
66+
5867

5968
## Enabling comparisons
6069

6170
There are two ways to enable this comparison using the Scala 3 `CanEqual` type class.
6271
For simple cases like this, your class can *derive* the `CanEqual` class:
6372

73+
{% tabs multiversal-equality-derives-CanEqual %}
74+
75+
{% tab 'Scala 3 Only' %}
76+
6477
```scala
6578
// Option 1
6679
case class Dog(name: String) derives CanEqual
6780
```
6881

82+
{% endtab %}
83+
84+
{% endtabs %}
85+
6986
As you’ll see in a few moments, when you need more flexibility you can also use this syntax:
7087

88+
{% tabs multiversal-equality-given-CanEqual %}
89+
90+
{% tab 'Scala 3 Only' %}
91+
7192
```scala
7293
// Option 2
7394
case class Dog(name: String)
7495
given CanEqual[Dog, Dog] = CanEqual.derived
7596
```
7697

98+
{% endtab %}
99+
100+
{% endtabs %}
101+
77102
Either of those two approaches now let `Dog` instances to be compared to each other.
78103

79104

@@ -82,11 +107,19 @@ Either of those two approaches now let `Dog` instances to be compared to each ot
82107
In a more real-world example, imagine you have an online bookstore and want to allow or disallow the comparison of physical, printed books, and audiobooks.
83108
With Scala 3 you start by enabling multiversal equality as shown in the previous example:
84109

110+
{% tabs multiversal-equality-strictEquality-2 %}
111+
112+
{% tab 'Scala 3 Only' %}
113+
85114
```scala
86115
// [1] add this import, or this command line flag: -language:strictEquality
87116
import scala.language.strictEquality
88117
```
89118

119+
{% endtab %}
120+
121+
{% endtabs %}
122+
90123
Then create your domain objects as usual:
91124

92125
```scala
@@ -113,6 +146,10 @@ case class AudioBook(
113146

114147
Finally, use `CanEqual` to define which comparisons you want to allow:
115148

149+
{% tabs multiversal-equality-CanEqual-allow-comps %}
150+
151+
{% tab 'Scala 3 Only' %}
152+
116153
```scala
117154
// [3] create type class instances to define the allowed comparisons.
118155
// allow `PrintedBook == PrintedBook`
@@ -131,6 +168,10 @@ val aBook = AudioBook("1984", "George Orwell", 2006, 682)
131168
println(pBook == aBook) // compiler error
132169
```
133170

171+
{% endtab %}
172+
173+
{% endtabs %}
174+
134175
The last line of code results in this compiler error message:
135176

136177
````
@@ -145,12 +186,20 @@ This is how multiversal equality catches illegal type comparisons at compile tim
145186
That works as desired, but in some situations you may want to allow the comparison of physical books to audiobooks.
146187
When you want this, create these two additional equality comparisons:
147188

189+
{% tabs multiversal-equality-additional-comps %}
190+
191+
{% tab 'Scala 3 Only' %}
192+
148193
```scala
149194
// allow `PrintedBook == AudioBook`, and `AudioBook == PrintedBook`
150195
given CanEqual[PrintedBook, AudioBook] = CanEqual.derived
151196
given CanEqual[AudioBook, PrintedBook] = CanEqual.derived
152197
```
153198

199+
{% endtab %}
200+
201+
{% endtabs %}
202+
154203
Now you can compare physical books to audiobooks without a compiler error:
155204

156205
```scala

0 commit comments

Comments
 (0)