Topic | Type Bounds In scala |
---|---|
Git sample | TypeBoundTest.scala ViewBoundTest.scala |
References | docs.scala-lang.org docs.scala-lang.org journaldev.com stackoverflow.com |
-
Methods in Scala can be parameterized by type as well as value. The syntax is similar to that of generic classes of Java
-
Type parameters are declared within a pair of brackets while value parameters are enclosed in a pair of parentheses
def listOfDuplicates[A](x: A, length: Int): List[A] = {
if (length < 1)
Nil
else
x :: listOfDuplicates(x, length - 1)
}
println(listOfDuplicates[Int](3, 4)) // List(3, 3, 3, 3)
println(listOfDuplicates("La", 8)) // List(La, La, La, La, La, La, La, La)
-
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
-
Scala type bounds helps in Type-Safe application development
-
Scala supports following type bounds
- Upper bounds : it limits a type to a Subtype of another type e.g.
[T <: Ordered[T]]
- Lower bounds : it limits a type to be a Supertype of another type e.g. e.g.
[T >: Ordered[T]]
- View bounds : use implicit conversions automatically
- Upper bounds : it limits a type to a Subtype of another type e.g.
-
Upper bounds
- An upper type bound term
T <: A
expresses that type variableT
refers to a Subtype of typeA
- An upper type bound term
-
Lower bounds
- A lower type bounds term
T >: A
expresses that the type variableT
refers to a Supertype of typeA
- A lower type bounds term
object TypeBoundTest extends App {
val animal = new Animal
val dog = new Dog
val puppy = new Puppy
val animalCarer = new AnimalCarer
/* Compilation Error : 'type mismatch; found : com.inbravo.lang.Animal required: T' */
/* animalCarer.display(animal) */
animalCarer.upperBoundBasedMethod(dog)
animalCarer.upperBoundBasedMethod(puppy)
/* Method 'feed' can accept all supertypes of 'Puppy' class not not any subtypes of 'Puppy' class */
animalCarer.lowerBoundBasedMethod(animal)
animalCarer.lowerBoundBasedMethod(dog)
animalCarer.lowerBoundBasedMethod(puppy)
}
/* Top most generalization */
class Animal
/* Specific 'Animal' types */
class Dog extends Animal
class Puppy extends Dog
class LabradorPuppy extends Puppy
class AnimalCarer {
/* This method accepts only either Dog class object or subclass type (i.e. Puppy) of Dog Class */
/* Type bound expression [T <: Dog] says that 'T' can only be a subtype of 'Dog' */
/* Upper bound is applied */
def upperBoundBasedMethod[T <: Dog](t: T) = println(t)
/* This method accepts only either Puppy class object or superclass type (i.e. LabradorPuppy) of Puppy Class */
/* Type bound expression [T >: Puppy] says that 'T' can only be a supertype of 'Puppy' */
/* Lower bound is applied */
def lowerBoundBasedMethod[T >: Puppy](t: T) = println(t)
}
- View bounds
- Please be aware that view bounds are deprecated
- A view bounds term
[T <% Ordered[T]
expresses thatT
should have an implicit conversion toOrdered[T]
, so that one can callT
methods on an object of typeOrdered[T]
/* Scala’s View Bound operator '<%' */
object ViewBoundTest extends App {
val p1 = new Person("A", "D")
val p2 = new Person("E", "A")
val p3 = new Person("G", "A")
println(p1.greater)
println(p2.greater)
println(p3.greater)
}
/* Scala’s View Bound operator '<%' means that 'T' should have an implicit conversion to 'Ordered[T]' available */
class Person[T <% Ordered[T]](val firstName: T, val lastName: T) {
def greater = if (firstName > lastName) firstName else lastName
}