Skip to content

Commit 1934ab4

Browse files
authored
Merge pull request #2552 from flomebul/compound-types
Add code tabs for _tour/compound-types
2 parents e0e4289 + def30dd commit 1934ab4

File tree

1 file changed

+54
-10
lines changed

1 file changed

+54
-10
lines changed

_tour/compound-types.md

+54-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: tour
3-
title: Compound Types
3+
title: Intersection Types, aka Compound Types
44
partof: scala-tour
55

66
num: 26
@@ -10,42 +10,86 @@ previous-page: abstract-type-members
1010
redirect_from: "/tutorials/tour/compound-types.html"
1111
---
1212

13-
Sometimes it is necessary to express that the type of an object is a subtype of several other types. In Scala this can be expressed with the help of *compound types*, which are intersections of object types.
13+
Sometimes it is necessary to express that the type of an object is a subtype of several other types.
14+
15+
In Scala this can be expressed with the help of *intersection types*, (or *compound types* in
16+
Scala 2) which are types that behave like any part of the intersection.
1417

1518
Suppose we have two traits `Cloneable` and `Resetable`:
1619

20+
{% tabs compound-types_1 class=tabs-scala-version %}
21+
{% tab 'Scala 2' for=compound-types_1 %}
1722
```scala mdoc
1823
trait Cloneable extends java.lang.Cloneable {
19-
override def clone(): Cloneable = {
24+
override def clone(): Cloneable = { // makes clone public
2025
super.clone().asInstanceOf[Cloneable]
2126
}
2227
}
2328
trait Resetable {
2429
def reset: Unit
2530
}
2631
```
32+
{% endtab %}
33+
{% tab 'Scala 3' for=compound-types_1 %}
34+
```scala
35+
trait Cloneable extends java.lang.Cloneable:
36+
override def clone(): Cloneable = // makes clone public
37+
super.clone().asInstanceOf[Cloneable]
38+
trait Resetable:
39+
def reset: Unit
40+
```
41+
{% endtab %}
42+
{% endtabs %}
2743

2844
Now suppose we want to write a function `cloneAndReset` which takes an object, clones it and resets the original object:
2945

30-
```
46+
{% tabs compound-types_2 class=tabs-scala-version %}
47+
{% tab 'Scala 2' for=compound-types_2 %}
48+
```scala mdoc:fail
3149
def cloneAndReset(obj: ?): Cloneable = {
3250
val cloned = obj.clone()
3351
obj.reset
3452
cloned
3553
}
3654
```
55+
{% endtab %}
56+
{% tab 'Scala 3' for=compound-types_2 %}
57+
```scala
58+
def cloneAndReset(obj: ?): Cloneable =
59+
val cloned = obj.clone()
60+
obj.reset
61+
cloned
62+
```
63+
{% endtab %}
64+
{% endtabs %}
3765

38-
The question arises what the type of the parameter `obj` is. If it's `Cloneable` then the object can be `clone`d, but not `reset`; if it's `Resetable` we can `reset` it, but there is no `clone` operation. To avoid type casts in such a situation, we can specify the type of `obj` to be both `Cloneable` and `Resetable`. This compound type is written like this in Scala: `Cloneable with Resetable`.
66+
The question arises what the type of the parameter `obj` is. If it's `Cloneable` then the object can be `clone`d, but not `reset`; if it's `Resetable` we can `reset` it, but there is no `clone` operation. To avoid type casts in such a situation, we can specify the type of `obj` to be both `Cloneable` and `Resetable`.
67+
{% tabs compound-types_3 class=tabs-scala-version %}
68+
{% tab 'Scala 2' for=compound-types_3 %}
69+
This compound type is written in Scala as `Cloneable with Resetable`.
3970

4071
Here's the updated function:
41-
42-
```
72+
```scala mdoc:fail
4373
def cloneAndReset(obj: Cloneable with Resetable): Cloneable = {
4474
//...
4575
}
4676
```
77+
Note that you can have more than two types: `A with B with C with ...`.
78+
This means the same as thing as `(...(A with B) with C) with ... )`
79+
{% endtab %}
80+
{% tab 'Scala 3' for=compound-types_3 %}
81+
This intersection type is written in Scala as `Cloneable & Resetable`.
4782

48-
Compound types can consist of several object types and they may have a single refinement which can be used to narrow the signature of existing object members.
49-
The general form is: `A with B with C ... { refinement }`
83+
Here's the updated function:
84+
```scala
85+
def cloneAndReset(obj: Cloneable & Resetable): Cloneable = {
86+
//...
87+
}
88+
```
89+
<!-- Compound types can consist of several object types and they may have a single refinement which can be used to narrow the signature of existing object members. -->
90+
Note that you can have more than two types: `A & B & C & ...`.
91+
And `&` is associative, so parentheses can be added around any part without changing the meaning.
92+
{% endtab %}
93+
{% endtabs %}
5094

51-
An example for the use of refinements is given on the page about [class composition with mixins](mixin-class-composition.html).
95+
<!-- An example for the use of refinements is given on the page about [class composition with mixins](mixin-class-composition.html). -->

0 commit comments

Comments
 (0)