@@ -5,70 +5,14 @@ title: "Intersection Types - More Details"
5
5
6
6
## Syntax
7
7
8
- Syntactically, an intersection type ` S & T ` is similar to an infix type,
9
- where the infix operator is ` & ` .
8
+ Syntactically, an intersection type ` S & T ` is similar to an infix type, where
9
+ the infix operator is ` & ` . ` & ` is treated as a soft keyword. That is, it is a
10
+ normal identifier with the usual precedence. But a type of the form A & B is
11
+ always recognized as an intersection type, without trying to resolve &.
10
12
11
13
```
12
14
Type ::= ...| InfixType
13
15
InfixType ::= RefinedType {id [nl] RefinedType}
14
- RefinedType ::= WithType {[nl] Refinement}
15
- WithType ::= AnnotType {‘with’ AnnotType}
16
- ```
17
-
18
- ## Type Checking
19
-
20
- The type ` S & T ` represents values that are of the type ` S ` and ` T ` at the same time.
21
-
22
- ``` scala
23
- trait Resettable {
24
- def reset (): this .type
25
- }
26
- trait Growable [T ] {
27
- def add (x : T ): this .type
28
- }
29
- def f (x : Resettable & Growable [String ]) = {
30
- x.reset()
31
- x.add(" first" )
32
- }
33
- ```
34
-
35
- The value ` x ` is required to be _ both_ a ` Resettable ` and a
36
- ` Growable[String] ` .
37
-
38
- The members of an intersection type ` A & B ` are all the members of ` A ` and all
39
- the members of ` B ` . For instance ` Resettable & Growable[String] `
40
- has member methods ` reset ` and ` add ` .
41
-
42
- If a member appears in both ` A ` and ` B ` , its type in ` A & B ` is the intersection
43
- of its type in ` A ` and its type in ` B ` . For instance, assume the definitions:
44
-
45
- ``` scala
46
- trait A {
47
- def children : List [A ]
48
- }
49
- trait B {
50
- def children : List [B ]
51
- }
52
- val x : A & B = new C
53
- val ys : List [A & B ] = x.children
54
- ```
55
-
56
- The type of ` children ` in ` A & B ` is the intersection of ` children ` 's
57
- type in ` A ` and its type in ` B ` , which is ` List[A] & List[B] ` . This
58
- can be further simplified to ` List[A & B] ` because ` List ` is
59
- covariant.
60
-
61
- An intersection type ` A & B ` may not be inhabited, e.g. ` Int & String ` is not inhabited.
62
- ` A & B ` is just a type that represents a set of requirements for
63
- values of the type. At the point where a value is _ constructed_ , one
64
- must make sure that all inherited members are correctly defined.
65
- So if one defines a class ` C ` that inherits ` A ` and ` B ` , one needs
66
- to give at that point a definition of a ` children ` method with the required type.
67
-
68
- ``` scala
69
- class C extends A with B {
70
- def children : List [A & B ] = ???
71
- }
72
16
```
73
17
74
18
## Subtyping Rules
@@ -91,6 +35,36 @@ From the rules above, we can show that `&` is _commutative_: `A & B <: B & A` fo
91
35
In another word, ` A & B ` is the same type as ` B & A ` , in that sense that the two types
92
36
have the same values and are subtypes of each other.
93
37
38
+ If ` C ` is a type constructor, the join ` C[A] & C[B] ` is simplified by pulling the
39
+ intersection inside the constructor, using the following two rules:
40
+
41
+ - If ` C ` is covariant, ` C[A] & C[B] ~> C[A & B] `
42
+ - If ` C ` is contravariant, ` C[A] & C[B] ~> C[A | B] `
43
+
44
+ When ` C ` is covariant, ` C[A & B] <: C[A] & C[B] ` can be derived:
45
+
46
+ ```
47
+ A <: A B <: B
48
+ ---------- ---------
49
+ A & B <: A A & B < B
50
+ --------------- -----------------
51
+ C[A & B] <: C[A] C[A & B] <: C[B]
52
+ ------------------------------------------
53
+ C[A & B] <: C[A] & C[B]
54
+ ```
55
+
56
+ When ` C ` is contravariant, ` C[A | B] <: C[A] & C[B] ` can be derived:
57
+
58
+ ```
59
+ A <: A B <: B
60
+ ---------- ---------
61
+ A <: A | B B < A | B
62
+ ------------------- ----------------
63
+ C[A | B] <: C[A] C[A | B] <: C[B]
64
+ --------------------------------------------------
65
+ C[A | B] <: C[A] & C[B]
66
+ ```
67
+
94
68
## Erasure
95
69
96
70
The erased type for ` S & T ` is the erased _ glb_ (greatest lower bound) of the
0 commit comments