Scala type constraints =:= and <:<
object TypeConstraints{
// Define some hierarchy
trait Pet
class Dog(name:String) extends Pet
object Dog{
def apply(name:String):Dog = new Dog(name)
}
case class Alsatian(name:String) extends Dog(name)
case class Cat(name:String) extends Pet
// Define methods with constraints
def sameTypeWrong[T <: Pet](a:T, b:T):Boolean = true
def sameTypeCorrect[T <: Pet, U](a:T, b:U)(implicit ev: T =:= U):Boolean = true
def subTypeWrong[T <: U, U](a:T, b:U):Boolean = true
def subTypeCorrect[T <: Pet, U](a:T, b:U)(implicit ev: T <:< U):Boolean = true
// Try them, to check whether they compile
sameTypeWrong(Cat("a"), Dog("b"))
// Does not compile: sameTypeCorrect(Cat("a"),new Dog("b"))
sameTypeCorrect(Cat("a"),Cat("b"))
subTypeWrong(Cat("a"), Dog("a"))
// Does not compile: subTypeCorrect(Cat("a"),Dog("b"))
subTypeCorrect(Alsatian("a"), Dog("a"))
}