[英]Scala Generics and Numeric Implicits
我需要将两个函数作为参数传递给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))
}
这要求类型R
和S
可以转换为已知Numeric[A]
距离的某种类型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]
扩展时,您仍然必须提供类型信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.