2017-01-12 2 views
2

Следующий код не компилируется, так как оба оператора умножения имеют одинаковый тип после стирания: (f: Object)ObjectВ Scala все абстрактные типы имеют одинаковый тип после стирания

Я знаю о типа стиранию, но во всех случаях я видел удалил общий тип, например List[Int] или List[String], как указано в Scala double definition (2 methods have the same type erasure).

Как я могу использовать Scala для разных типов XxxT`?

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

ответ

6

Это то, что DummyImplicit для:

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

У вас может быть любое количество DummyImplicit с, если вам нужно больше перегрузок, стирание которых одинаково.

0

Используя один из фокусов от answer к связанному вопросу (объявление параметра метода секунд, как вызов по имени):

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) 
+0

Интересный трюк, но он немного меняет семантику. Например, если вы используете функцию вместо значения, каждое использование снова вызывает функцию. –