score:7

Accepted answer

This is what DummyImplicit is for:

trait AbstractTypes {
  type ScalarT
  type VectorT
  abstract class Operators(u: VectorT) {
    def *(f: ScalarT): VectorT
    def *(v: VectorT)(implicit dummy1: DummyImplicit): VectorT
  }
}

You can have any number of DummyImplicits if you need more overloads whose erasure are the same.

score:0

Using one of the tricks from answer to the linked question (declaring parameter of the seconds method as call-by-name):

trait AbstractTypes {
  type ScalarT
  type VectorT
  abstract class Operators(u: VectorT) {
    def *(f: ScalarT): VectorT
    def *(v: => VectorT): VectorT
  }
}

object ConcreteTypes extends AbstractTypes {
  type ScalarT = Double
  type VectorT = Seq[Double]
  class ConcreteOperators(u: Seq[Double]) extends Operators(u) {
    def *(f: Double): Seq[Double] = u.map(_ * f)
    def *(v: => Seq[Double]): Seq[Double] = 
      (u zip v).map { case (a, b) => a * b }
  }
}

new ConcreteTypes.ConcreteOperators(Seq(2.0, 3.0, 5.0)) * 7.0 
Seq[Double] = List(14.0, 21.0, 35.0)

new ConcreteTypes.ConcreteOperators(Seq(2.0, 3.0, 5.0)) * Seq(1.0, 2.0, 3.0) 
Seq[Double] = List(2.0, 6.0, 15.0)

Related Query

More Query from same tag