Skip to content

Add code tabs for _tour/upper-type-bounds #2548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 22, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions _tour/upper-type-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ redirect_from: "/tutorials/tour/upper-type-bounds.html"
In Scala, [type parameters](generic-classes.html) and [abstract type members](abstract-type-members.html) may be constrained by a type bound. Such type bounds limit the concrete values of the type variables and possibly reveal more information about the members of such types. An _upper type bound_ `T <: A` declares that type variable `T` refers to a subtype of type `A`.
Here is an example that demonstrates upper type bound for a type parameter of class `PetContainer`:

{% tabs upper-type-bounds class=tabs-scala-version %}
{% tab 'Scala 2' for=upper-type-bounds %}
```scala mdoc
abstract class Animal {
def name: String
Expand All @@ -39,11 +41,47 @@ class PetContainer[P <: Pet](p: P) {
val dogContainer = new PetContainer[Dog](new Dog)
val catContainer = new PetContainer[Cat](new Cat)
```
{% endtab %}
{% tab 'Scala 3' for=upper-type-bounds %}
```scala
abstract class Animal:
def name: String

abstract class Pet extends Animal

class Cat extends Pet:
override def name: String = "Cat"

class Dog extends Pet:
override def name: String = "Dog"

class Lion extends Animal:
override def name: String = "Lion"

class PetContainer[P <: Pet](p: P):
def pet: P = p

val dogContainer = PetContainer[Dog](Dog())
val catContainer = PetContainer[Cat](Cat())
```
{% endtab %}
{% endtabs %}

{% tabs upper-type-bounds_error class=tabs-scala-version %}
{% tab 'Scala 2' for=upper-type-bounds_error %}
```scala mdoc:fail
// this would not compile
val lionContainer = new PetContainer[Lion](new Lion)
```
{% endtab %}
{% tab 'Scala 3' for=upper-type-bounds_error %}
```scala
// this would not compile
val lionContainer = PetContainer[Lion](Lion())
```
{% endtab %}
{% endtabs %}

The `class PetContainer` takes a type parameter `P` which must be a subtype of `Pet`. `Dog` and `Cat` are subtypes of `Pet` so we can create a new `PetContainer[Dog]` and `PetContainer[Cat]`. However, if we tried to create a `PetContainer[Lion]`, we would get the following Error:

`type arguments [Lion] do not conform to class PetContainer's type parameter bounds [P <: Pet]`
Expand Down