I would recommend defining a typeclass for common algebraic operations:
trait Algebra[A] {
def plus(x: A, y: A): A
def timesScalar(x: A, d: Double): A
}
implicit val vectorAlgebra = new Algebra[Vector] {
def plus(x: Vector, y: Vector): Vector = x + y
}
// ... same for Matrix ...
def update[A](x: A, y: A)(implicit alg: Algebra[A]): A = {
alg.plus(x, alg.timesScalar(y, 0.5))
}
You can also look into simulacrum if you want to easily generate some syntactical sugar for the typeclass so you could in theory do something simpler like:
def update[A : Algebra](x: A, y: A): A = {
x + (y * 0.5)
}
An entirely different approach would be more OO-based, and make a common trait like Algebraic that both Vector and Matrix could inherit from. But that's tougher when they're coming from other libraries, so you end up having to wrap them in your own classes. And then you hit complications with F-bounded polymorphism... I'd just go with the typeclass.
Matrix?