0

Imagine the following class

class A{
    def update(x: Vector, y: Vector): Vector = {
        x + 0.5 * y
    }

    def update(x: Matrix, y: Matrix): Matrix = {
        x + 0.5 * y
    }
}

The only difference between both methods is the input type. What would be the correct way of unifying these methods and avoid duplicating code in Scala?

2
  • what's a Matrix? Commented Jul 11, 2018 at 20:29
  • I'm working with Breeze's DenseMatrix and DenseVector, but I'm wondering whats the general solution for this problem in Scala. Commented Jul 11, 2018 at 20:32

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.