@@ -5,70 +5,14 @@ title: "Intersection Types - More Details"
55
66## Syntax
77
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 &.
1012
1113```
1214Type ::= ...| InfixType
1315InfixType ::= 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- }
7216```
7317
7418## Subtyping Rules
@@ -91,6 +35,36 @@ From the rules above, we can show that `&` is _commutative_: `A & B <: B & A` fo
9135In another word, ` A & B ` is the same type as ` B & A ` , in that sense that the two types
9236have the same values and are subtypes of each other.
9337
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+
9468## Erasure
9569
9670The erased type for ` S & T ` is the erased _ glb_ (greatest lower bound) of the
0 commit comments