Generics Scala泛型及其数值隐式

Generics Scala泛型及其数值隐式,generics,scala,numeric,implicit,Generics,Scala,Numeric,Implicit,我需要将两个函数作为参数传递给scala函数。然后,该函数应该对它们进行求值,并从中获取一个数字,然后对其进行操作。此数字可以是Int、Double或任何其他数字类型。我希望这个函数能够工作,不管它使用什么类型 下面的例子解释了这个问题 import Numeric.Implicits._ class Arithmetic[T : Numeric](val A: Connector[T], val B: Connector[T]) { val sum = new Connector({

我需要将两个函数作为参数传递给scala函数。然后,该函数应该对它们进行求值,并从中获取一个数字,然后对其进行操作。此数字可以是Int、Double或任何其他数字类型。我希望这个函数能够工作,不管它使用什么类型

下面的例子解释了这个问题

import Numeric.Implicits._

class Arithmetic[T : Numeric](val A: Connector[T], val B: Connector[T]) {
  val sum  = new Connector({ A.value + B.value })
}

class Constant[T](var x: T) {
  val value = new Connector({ x })
}

class Connector[T](f: => T) {
  def value: T = f
  override def toString = value.toString()
}

object Main extends App{
  val n1 = new Constant(1)

  // works
  val n5 = new Constant(5)
  val a = new Arithmetic( n1.value, n5.value )
  println(a.sum)

 // no works
 val n55 = new Constant(5.5)
 val b = new Arithmetic( n1.value, n55.value )
 println(b.sum)

}
我也试过了

class Arithmetic[T,R : Numeric](val A: Connector[T], val B: Connector[R]) {
还有其他几种组合,但我最终

error: could not find implicit value for parameter num: scala.math.Numeric[Any]
val sum  = new Connector({ A.value + B.value })

您看到的错误消息是因为
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))
}

加宽时,您仍然需要提供类型信息。

您的第一个解决方案有效吗?编译器会抱怨b.value应该是字符串。@Moritz,当你的第二个建议有效时,我仍然有义务在它们不同时插入类型。这是行不通的,因为我不知道将来会出现什么类型的算术。它应该是自动的,就像你在REPL中写2+4.1并得到6.1一样。@Moritz,至于你的第一个建议,我无法让它也工作。错误:不明确的隐式值:object scala.math.Numeric.biginitisintegral类型的object Numeric中的object biginitisintegral和object scala.math.Numeric.IntIsIntegral类型的object Numeric中的object IntIsIntegral都与预期的type Numeric[A]val A=新算术(n1.value,n5.value)匹配,其中n1和n5是常量。@HugoSFerreira,@tiagoboldt:如果使用第一个示例,则在构造实例时必须向提供所有类型参数,例如:
新算术[Double,Int,Double](intConn,dblConn)
,因为它们无法推断。@HugoSFerreira是否忘记了导入数值隐式。?
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]