From Scala 2.8 onwards parameterized types have been afforded even more constraint capabilities via generalized type constraint classes. These classes enable further specialisation in methods, and complement context bounds, as follows:
A =:= B asserts that A and B must be the equal
A <:< B asserts that A must be a subtype of B
A sample usage of these classes would be to enable a specialization for addition of numeric elements in a collection, or for bespoke print formatting, or to allow for customized liability calculations on specific bet or fund types in a traders portfolio. For example:
case class PrintFormatter[T](item : T) {
def formatString(implicit evidence: T =:= String) = { // Will only work for String PrintFormatters
println("STRING specialised printformatting...")
}
def formatPrimitive(implicit evidence: T <:< AnyVal) = { // Will only work for Primitive PrintFormatters
println("WRAPPED PRIMITIVE specialised printformatting...")
}
}
val stringPrintFormatter = PrintFormatter("String to format...")
stringPrintFormatter formatString
// stringPrintFormatter formatPrimitive // Will not compile due to type mismatch
val intPrintFormatter = PrintFormatter(123)
intPrintFormatter formatPrimitive
// intPrintFormatter formatString // Will not compile due to type mismatch
You can find a whole short course about Scala types here: http://scalabound.org/?p=323