Scala Type Bounds: Upper Bounds, Lower Bounds and View Bounds

Filed Under: Scala

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:

scala_upper_bound

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:-


[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.


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.


//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:


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:

scala_lower_bound

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:-


[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:-


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:


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:

scala_view_bound

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).


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:-


Rams
Chintu

If we don’t use Scala’s View Bound operator “<%”, then we will get the following error message.


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.

Comments

  1. yash says:

    Hello Sir,

    i amended the code below and surprise to me it is working.
    class Animal
    class Dog extends Animal
    class Puppy extends Animal
    class Puppy1 extends Animal
    class Puppy2 extends Puppy

    class AnimalCarer{
    def display [T >: Puppy](t: T){
    println(t)
    }
    }

    val animal = new Animal
    val dog = new Dog
    val puppy = new Puppy
    val puppy1 = new Puppy1
    val puppy2 = new Puppy2

    val animalCarer = new AnimalCarer

    animalCarer.display(animal)
    animalCarer.display(puppy)
    animalCarer.display(puppy1)
    animalCarer.display(puppy2)
    animalCarer.display(dog)

    It should not as the upper bound is Puppy.

    1. Rambabu says:

      Thanks for reading my tutorials. Let me check it and update the same soon.

      Ram

  2. reddy sekhar says:

    hi sir can u suggest me good book for learning scala and play scala framework

    1. Rambabu says:

      Thanks to read my tutorials.

      You can find those info in my bolog: http://rams4java.blogspot.co.uk/2016/02/top-5-play-framework-books-must-read.html
      http://rams4java.blogspot.co.uk/2016/07/spring-boot-books-to-learn.html

      Choose one of them depends on your experience. If you have any questions, please come back to me.

      Ram

      1. krishnan says:

        ———–Scala Lower Bounds—————-

        class Animal
        class Puppy extends Animal
        class SmallPuppy extends Puppy

        class AnimalCarer{
        def display [T >: Puppy](t: T){
        println(t)
        }
        }

        object ScalaLowerBoundsTest {
        def main(args: Array[String]) {

        val animal = new Animal
        val sp = new SmallPuppy
        val puppy = new Puppy

        val animalCarer = new AnimalCarer

        animalCarer.display(animal)
        animalCarer.display(puppy)
        animalCarer.display(sp)
        }
        }

        animalCarer method accepts any class which is subclass of Puppy in LOWERBOUND example.
        Is it fine?

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages