Skip to content

Commit e39e683

Browse files
committed
Type Lambdas Spec
1 parent 85f109f commit e39e683

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
layout: doc-page
3+
title: "Type Lambdas - More Details"
4+
---
5+
6+
## Syntax
7+
8+
```
9+
Type ::= ... | HkTypeParamClause ‘=>’ Type
10+
HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’
11+
HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (Id[HkTypeParamClause] | ‘_’) TypeBounds
12+
TypeBounds ::= [‘>:’ Type] [‘<:’ Type]
13+
```
14+
15+
### Type Checking
16+
17+
A type lambda such `[X] => F[X]` defines a function from types to types. The parameter(s) may carry bounds and variance annotations.
18+
If a parameter is is bounded, as in `[X >: L <: H] => F[X]` it is checked that arguments to the parameters conform to the bounds `L` and `H`.
19+
Only the upper bound `H` can be F-bounded, i.e. `X` can appear in it.
20+
21+
A variance annotation on a parameter indicates a subtyping relationship on type instances. For instance, given
22+
```
23+
type TL1 = [+A] => F[A]
24+
type TL2 = [-A] => F[A]
25+
```
26+
and two types `S <: T`, we have
27+
```
28+
TL1[S] <: TL1[T
29+
TL2[T] <: TL2[S]
30+
```
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.
33+
34+
## Subtyping Rules
35+
36+
Assume two type lambdas
37+
```
38+
type TL1 = [v1 X >: L1 <: U1] => R1
39+
type TL2 = [v2 X >: L2 <: U2] => R2
40+
```
41+
where `v1` and `v2` are optional variance annotations: `+`, `-`, or absent.
42+
Then `TL1 <: TL2`, if the type interval `L2..U2` is contained in the type interval `L1..U1` (i.e.
43+
`L1 <: L2` and `U2 <: U1`), and either `v2` is absent or `v1 = v2`.
44+
45+
46+
47+
48+
49+

docs/docs/reference/type-lambdas.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ is a shorthand for a plain type definition with a type-lambda as its
2020
right-hand side:
2121

2222
type T = [X] => (X, X)
23+
24+
[More details](./type-lambdas-spec.md)

tests/neg/type-lambdas.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
object Test extends App {
2+
3+
trait Ord[X]
4+
5+
type TL1 = [X <: Ord[X]] => (X, X) // OK
6+
type TL2 = [X >: Ord[X]] => (X, X) // error
7+
8+
class C extends Ord[C]
9+
10+
type T1 = TL1[Int] // will be discovered later
11+
type T2 = TL1[C] // OK
12+
13+
class Ref[X](init: X) {
14+
var x: X = init
15+
}
16+
17+
type TL3 = [+X] => Ref[X]
18+
19+
def f[F <: [+X] => Any](x: F[String]): F[Any] = x
20+
21+
val sref = new Ref[String]("abc")
22+
val aref: Ref[Any] = f[TL3](sref)
23+
aref.x = 1
24+
val s: String = sref.x
25+
26+
27+
28+
29+
}

0 commit comments

Comments
 (0)