Scala Generics and Numeric Implicits

爱⌒轻易说出口 提交于 2019-12-04 05:04:44

The error message you are seeing is because Numeric[T].plus can only be used to add two values of the same type T. Your code is written under the assumption that numeric widening happens automatically - which will not in this case as the compiler does not know anything about the types except that there exists a Numeric[T] instance.

If you need sum to be a stable value, you will have to provide the necessary type information in the constructor like this:

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))
}

This requires types R and S to be convertible into some type A for which a Numeric[A] istance is known. When creating an instance you would always have to provide all type parameters as they cannot be inferred.

If you do not need sum to be stable you could change your class to this:

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]

When widening you will still have to provide the type information though.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!