Skip to content

Commit 5934d7b

Browse files
committed
Flesh out spec to adress review comments.
1 parent 1c3f350 commit 5934d7b

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

docs/docs/reference/type-lambdas-spec.md

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,24 @@ If a parameter is is bounded, as in `[X >: L <: H] => F[X]` it is checked that a
1919
Only the upper bound `H` can be F-bounded, i.e. `X` can appear in it.
2020

2121
A variance annotation on a parameter indicates a subtyping relationship on type instances. For instance, given
22-
```
22+
```scala
2323
type TL1 = [+A] => F[A]
2424
type TL2 = [-A] => F[A]
2525
```
2626
and two types `S <: T`, we have
27-
```
28-
TL1[S] <: TL1[T
27+
```scala
28+
TL1[S] <: TL1[T]
2929
TL2[T] <: TL2[S]
3030
```
31-
It is checked that variance annotations on parameters of type lambdas are respected by the parameter occurrences on the
32-
type lambda's body.
31+
It is checked that variance annotations on parameters of type lambdas are respected by the parameter occurrences on the type lambda's body.
32+
33+
**Note** No requirements hold for the variances of occurrences of type variables in their bounds. It is an open question whether we need to impose additional requirements here
34+
(`scalac` doesn't check variances in bounds either).
3335

3436
## Subtyping Rules
3537

3638
Assume two type lambdas
37-
```
39+
```scala
3840
type TL1 = [v1 X >: L1 <: U1] => R1
3941
type TL2 = [v2 X >: L2 <: U2] => R2
4042
```
@@ -45,41 +47,55 @@ Then `TL1 <: TL2`, if the type interval `L2..U2` is contained in the type interv
4547
## Relationship with Parameterized Type Definitions
4648

4749
A parameterized type definition
48-
```
50+
```scala
4951
type T[X] = R
5052
```
5153
is regarded as a shorthand for an unparameterized definition with a type lambda as right-hand side:
52-
```
54+
```scala
5355
type T = [X] => R
5456
```
5557

5658
A parameterized abstract type
57-
```
59+
```scala
5860
type T[X] >: L <: U
5961
```
6062
is regarded as shorthand for an unparameterized abstract type with type lambdas as bounds.
61-
```
63+
```scala
6264
type T >: ([X] => L) <: ([X] => U)
6365
```
6466
However, if `L` is `Nothing` it is not parameterized, since `Nothing` is treated as a bottom type for all kinds. For instance,
65-
```
67+
```scala
6668
type T[-X] <: X => ()
6769
```
6870
is expanded to
69-
```
71+
```scala
7072
type T >: Nothing <: ([-X] => X => ())
7173
```
7274
instead of
73-
```
75+
```scala
7476
type T >: ([X] => Nothing) <: ([-X] => X => ())
7577
```
7678

79+
The same expansions apply to type parameters. E.g.
80+
```scala
81+
[F[X] <: Coll[X]]
82+
```
83+
is treated as a shorthand for
84+
```scala
85+
[F >: Nothing <: [X] => Coll[X]]
86+
```
87+
7788
**Note**: The decision to treat `Nothing` as universal bottom type is provisional, and might be changed afer further discussion.
7889

7990
**Note**: Scala 2 and 3 differ in that Scala 2 also treats `Any` as universal top-type. This is not done in Scala 3. See also the discussion on [kind polymorphism](./kind-polymorphism.html)
8091

92+
## Curried Type Parameters
8193

82-
94+
The body of a type lambda can again be a type lambda. Example:
95+
```scala
96+
type TL = [X] => [Y] => (X, Y)
97+
```
98+
Currently, no special provision is made to infer type arguments to such curried type lambdas. This is left for future work.
8399

84100

85101

tests/pos/reference/type-lambdas.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,9 @@ object Test {
44

55
type T = [+X, Y] => Map[Y, X]
66

7+
type CTL = [X] => [Y] => (X, Y)
8+
type T3 = CTL[Int][String]
9+
10+
type T2[+X <: X => X] = Any
11+
class C[+X <: X => Unit]
712
}

0 commit comments

Comments
 (0)