I think the reason Scala requires the type annotation on the parameters of a newly defined function comes from the fact that Scala uses a more local type inference analysis than that used in Haskell.
If all your classes mixed in a trait, say Addable[T]
, that declared the +
operator, you could write your generic add function as:
def add[T <: Addable[T]](x : T, y : T) = x + y
This restricts the add function to types T that implement the Addable trait.
Unfortunately, there is not such trait in the current Scala libraries. But you can see how it would be done by looking at a similar case, the Ordered[T]
trait. This trait declares comparison operators and is mixed in by the RichInt
, RichFloat
, etc. classes. Then you can write a sort function that can take, for example, a List[T]
where [T <: Ordered[T]]
to sort a list of elements that mix in the ordered trait. Because of implicit type conversions like Float
to RichFloat
, you can even use your sort function on lists of Int
, or Float
or Double
.
As I said, unfortunately, there is no corresponding trait for the +
operator. So, you would have to write out everything yourself. You would do the Addable[T] trait, create AddableInt
, AddableFloat
, etc., classes that extend Int, Float, etc. and mix in the Addable trait, and finally add implicit conversion functions to turn, for example, and Int into an AddableInt
, so that the compiler can instantiate and use your add function with it.