You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While [upper type bounds](upper-type-bounds.html) limit a type to a subtype of another type, *lower type bounds* declare a type to be a supertype of another type. The term `T >: A` expresses that the type parameter `T` or the abstract type `T` refer to a supertype of type `A`. In most cases, `A` will be the type parameter of the class and `T` will be the type parameter of a method.
15
+
While [upper type bounds](upper-type-bounds.html) limit a type to a subtype of another type, *lower type bounds* declare a type to be a supertype of another type. The term `B >: A` expresses that the type parameter `B` or the abstract type `B` refer to a supertype of type `A`. In most cases, `A` will be the type parameter of the class and `B` will be the type parameter of a method.
16
16
17
17
Here is an example where this is useful:
18
18
19
19
```tut:fail
20
-
trait Node[+T] {
21
-
def prepend(elem: T)
20
+
trait Node[+B] {
21
+
def prepend(elem: B): Unit
22
22
}
23
23
24
-
case class ListNode[+T](h: T, t: Node[T]) extends Node[T] {
25
-
def prepend(elem: T) = ListNode[T](elem, this)
26
-
def head: T = h
24
+
case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
25
+
def prepend(elem: B) = ListNode[B](elem, this)
26
+
def head: B = h
27
27
def tail = t
28
28
}
29
29
30
-
case class Nil[+T]() extends Node[T] {
31
-
def prepend(elem: T) = ListNode[T](elem, this)
30
+
case class Nil[+B]() extends Node[B] {
31
+
def prepend(elem: B) = ListNode[B](elem, this)
32
32
}
33
33
```
34
-
This program implements a singly-linked list. `Nil` represents an empty element (i.e. an empty list). `class ListNode` is a node which contains an element of type `T` (`head`) and a reference to the rest of the list (`tail`). The `class Node` and its subtypes are covariant because we have `+T`.
34
+
This program implements a singly-linked list. `Nil` represents an empty element (i.e. an empty list). `class ListNode` is a node which contains an element of type `B` (`head`) and a reference to the rest of the list (`tail`). The `class Node` and its subtypes are covariant because we have `+B`.
35
35
36
-
However, this program does _not_ compile because the parameter `elem` in `prepend` is of type `T`, which we declared *co*variant. This doesn't work because functions are *contra*variant in their parameter types and *co*variant in their result types.
36
+
However, this program does _not_ compile because the parameter `elem` in `prepend` is of type `B`, which we declared *co*variant. This doesn't work because functions are *contra*variant in their parameter types and *co*variant in their result types.
37
37
38
-
To fix this, we need to flip the variance of the type of the parameter `elem` in `prepend`. We do this by introducing a new type parameter `U` that has `T` as a lower type bound.
38
+
To fix this, we need to flip the variance of the type of the parameter `elem` in `prepend`. We do this by introducing a new type parameter `U` that has `B` as a lower type bound.
39
39
40
40
```tut
41
-
trait Node[+T] {
42
-
def prepend[U >: T](elem: U)
41
+
trait Node[+B] {
42
+
def prepend[U >: B](elem: U)
43
43
}
44
44
45
-
case class ListNode[+T](h: T, t: Node[T]) extends Node[T] {
0 commit comments