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: _overviews/scala3-book/types-union.md
+59
Original file line number
Diff line number
Diff line change
@@ -7,12 +7,17 @@ num: 51
7
7
previous-page: types-intersection
8
8
next-page: types-adts-gadts
9
9
---
10
+
<spanclass="tag tag-inline">Scala 3 only</span>
10
11
11
12
Used on types, the `|` operator creates a so-called _union type_.
12
13
The type `A | B` represents values that are **either** of the type `A`**or** of the type `B`.
13
14
14
15
In the following example, the `help` method accepts a parameter named `id` of the union type `Username | Password`, that can be either a `Username` or a `Password`:
We implement the method `help` by distinguishing between the two alternatives using pattern matching.
27
36
28
37
This code is a flexible and type-safe solution.
29
38
If you attempt to pass in a type other than a `Username` or `Password`, the compiler flags it as an error:
30
39
40
+
{% tabs union-error-1 %}
41
+
42
+
{% tab 'Scala 3 Only' %}
43
+
31
44
```scala
32
45
help("hi") // error: Found: ("hi" : String)
33
46
// Required: Username | Password
34
47
```
35
48
49
+
{% endtab %}
50
+
51
+
{% endtabs %}
52
+
36
53
You’ll also get an error if you attempt to add a `case` to the `match` expression that doesn’t match the `Username` or `Password` types:
37
54
55
+
{% tabs union-error-2 %}
56
+
57
+
{% tab 'Scala 3 Only' %}
58
+
38
59
```scala
39
60
case1.0=>???// ERROR: this line won’t compile
40
61
```
41
62
63
+
{% endtab %}
64
+
65
+
{% endtabs %}
66
+
42
67
### Alternative to Union Types
43
68
As shown, union types can be used to represent alternatives of several different types, without requiring those types to be part of a custom-crafted class hierarchy, or requiring explicit wrapping.
44
69
45
70
#### Pre-planning the Class Hierarchy
46
71
Other languages would require pre-planning of the class hierarchy, like the following example illustrates:
Pre-planning does not scale very well since, for example, requirements of API users might not be foreseeable.
55
89
Additionally, cluttering the type hierarchy with marker traits like `UsernameOrPassword` also makes the code more difficult to read.
56
90
57
91
#### Tagged Unions
58
92
Another alternative is to define a separate enumeration type like:
59
93
94
+
{% tabs union-tagged-unions %}
95
+
96
+
{% tab 'Scala 3 Only' %}
97
+
60
98
```scala
61
99
enumUsernameOrPassword:
62
100
caseIsUsername(u: Username)
63
101
caseIsPassword(p: Password)
64
102
```
103
+
104
+
{% endtab %}
105
+
106
+
{% endtabs %}
107
+
65
108
The enumeration `UsernameOrPassword` represents a _tagged_ union of `Username` and `Password`.
66
109
However, this way of modeling the union requires _explicit wrapping and unwrapping_ and, for instance, `Username` is **not** a subtype of `UsernameOrPassword`.
67
110
68
111
### Inference of Union Types
69
112
The compiler assigns a union type to an expression _only if_ such a type is explicitly given.
0 commit comments