In my previous post, I have discussed about Scala Variance in detail. In this post, we are going to discuss about “Scala Type Bounds”.
What is Type Bound in Scala?
In Scala, Type Bounds are restrictions on Type Parameters or Type Variable. By using Type Bounds, we can define the limits of a Type Variable.
Advantage of Scala Type Bounds
Scala Type Bounds give us the following benefit:
- Type-Safe Application Development.
Scala Type Bounds
Scala supports the following Type Bounds for Type Variables:
- Scala Upper Bounds
- Scala Lower Bounds
- Scala View Bounds
We are going to discuss these concepts in detail with examples in next sections.
Scala Upper Bounds
In Scala, we can define Upper Bound on Type Parameter as shown below:
Description:-
Here T is a Type Parameter ans S is a type. By declaring Upper Bound like “[T <: S]” means this Type Parameter T must be either same as S or Sub-Type of S.
Example-1:-
1 2 3 |
[T <: Ordered[T]] |
Here We have defined Upper Bound from Type Parameter T to Type Ordered[T]. Then T much be either Ordered or subtype of Ordered type.
Example-2:-
Write a Scala program to demonstrate Scala Upper Bound.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class Animal class Dog extends Animal class Puppy extends Dog class AnimalCarer{ def display [T <: Dog](t: T){ println(t) } } object ScalaUpperBoundsTest { def main(args: Array[String]) { val animal = new Animal val dog = new Dog val puppy = new Puppy val animalCarer = new AnimalCarer //animalCarer.display(animal) animalCarer.display(dog) animalCarer.display(puppy) } } |
This program works fine with commenting the following line.
1 2 3 |
//animalCarer.display(animal) |
If we uncomment this line and try to run it, we will get compilation error. Because we have defined Upper Bound as shown below:
1 2 3 4 5 6 7 |
class AnimalCarer{ def display [T <: Dog](t: T){ println(t) } } |
Here we have defined “[T <: Dog]” that means “display” method accepts only either Dog class object or subclass type (i.e. Puppy) of Dog Class. That’s why if we pass Dog Super class, we will get “Type Mismatch” compilation error.
Scala Lower Bounds
In Scala, we can define Lower Bound on Type Parameter as shown below:
Description:-
Here T is a Type Parameter ans S is a type. By declaring Lower Bound like “[T >: S]” means this Type Parameter T must be either same as S or Super-Type of S.
Example-1:-
1 2 3 |
[T >: Ordered[T]] |
Here We have defined Lower Bound from Type Parameter T to Type Ordered[T]. Then T much be either Ordered or supertype of Ordered type.
Example-2:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class Animal class Dog extends Animal class Puppy extends Animal class AnimalCarer{ def display [T >: Puppy](t: T){ println(t) } } object ScalaLowerBoundsTest { def main(args: Array[String]) { val animal = new Animal val dog = new Dog val puppy = new Puppy val animalCarer = new AnimalCarer animalCarer.display(animal) animalCarer.display(puppy) animalCarer.display(dog) } } |
Here Dog is not a subtype of Puppy, but still this program works fine because Dog is a subtype of Animal and we have defined “Lower Bound” on Type Parameter T as shown below:
1 2 3 4 5 6 7 |
class AnimalCarer{ def display [T >: Puppy](t: T){ println(t) } } |
If we remove Lower Bound definition in this class, then we will get some compilation errors.
Scala View Bounds
In Scala, View Bound is used when we want to use existing Implicit Conversions automatically. We can define View Bound on Type Parameter as shown below:
Description:-
In some scenarios, we need to use some Implicit conversions automatically to solve our problem statement. We can use Scala’s View Bounds to utilize these Implicits.
Example:-
Write a Scala program to compare Strings with Relational operators(like Int’s 10 > 12).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Person[T <% Ordered[T]](val firstName: T, val lastName: T) { def greater = if (firstName > lastName) firstName else lastName } object ScalaViewBoundsTest { def main(args: Array[String]) { val p1 = new Person("Rams","Posa") val p2 = new Person("Chintu","Charan") println(p1.greater) println(p2.greater) } } |
Output:-
1 2 3 4 |
Rams Chintu |
If we don’t use Scala’s View Bound operator “<%”, then we will get the following error message.
1 2 3 |
error: value > is not a member of type parameter T |
That’s it all about Scala Upper Bounds, Lower Bounds and View Bounds. We will discuss some more Scala concepts in my coming posts.
Please drop me a comment if you like my post or have any issues/suggestions.