Ad hoc polymorphism is similar to parametric polymorphism; however, in this case, the type of arguments is important, as the concrete implementation will depend on it. It is resolved at compile time, unlike subtype polymorphism, which is done during runtime. This is somewhat similar to function overloading.
We saw an example of it earlier in this chapter, where we created the Adder trait that can sum different types. Let's have another one but a bit more refined and step by step, and we will hopefully understand how things work. Our goal is to have a sum method that can add many different kinds of types:
trait Adder[T] { def sum(a: T, b: T): T}
Next, we will create a Scala object that uses this sum method and exposes it ...