Вы видите сообщение об ошибке, потому что Numeric[T].plus
может использоваться только для добавления двух значений одного типа T
.
Ваш код написан в предположении, что расширение чисел происходит автоматически - что не произойдет в этом случае, так как компилятор ничего не знает о типах, за исключением того, что существует экземпляр Numeric[T]
.
Если вам нужно, чтобы sum
было стабильным значением, вы должны будете предоставить необходимую информацию о типе в конструкторе следующим образом:
class Arithmetic[A : Numeric, R <% A, S <% A](val a: Connector[R], b: Connector[S]) {
val sum = new Connector[A]((a.value:A) + (b.value:A))
}
Для этого требуется, чтобы типы R
и S
были преобразованы в некоторый тип A
, для которого известно значение Numeric[A]
.
При создании экземпляра вам всегда нужно будет указывать все параметры типа, поскольку они не могут быть выведены.
Если вам не нужна sum
для стабильности, вы можете изменить свой класс на:
class Arithmetic[A,B](val a: Connector[A], val b: Connector[B]) {
// if A and B are the same types
def sum(implicit e: B =:= A, n: Numeric[A]): Connector[A] =
new Connector(n.plus(a.value, b.value))
// else widen to C
def wideSum[C](implicit f: A => C, g: B => C, n: Numeric[C]) =
new Connector(n.plus(a.value, b.value))
}
val a = new Connector(1)
val b = new Connector(2)
val c = new Connector(3.0)
val d = (new Arithmetic(a,b)).sum
// val e = (new Arithmetic(b,c)).sum // <-- does not compile
val e = (new Arithmetic(b,c)).wideSum[Double]
При расширении вам все равно придется предоставить информацию о типе.