Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 如何使使用值[T:Numeric]的代码更“;灵活”;像“;未装箱的&x201D;相对应的人?_Generics_Scala_Numbers_Numeric_Implicit - Fatal编程技术网

Generics 如何使使用值[T:Numeric]的代码更“;灵活”;像“;未装箱的&x201D;相对应的人?

Generics 如何使使用值[T:Numeric]的代码更“;灵活”;像“;未装箱的&x201D;相对应的人?,generics,scala,numbers,numeric,implicit,Generics,Scala,Numbers,Numeric,Implicit,如果我有像5*5.0这样的代码,结果将转换为最精确的类型,Double 但这似乎不适用于这样的代码 case class Value[T : Numeric](value: T) { type This = Value[T] def +(m: This) = Value[T](implicitly[Numeric[T]].plus(value, m.value)) ... } implicit def numToValue[T : Numeric](v: T) = Va

如果我有像
5*5.0
这样的代码,结果将转换为最精确的类型,
Double

但这似乎不适用于这样的代码

case class Value[T : Numeric](value: T) {
    type This = Value[T]
    def +(m: This) = Value[T](implicitly[Numeric[T]].plus(value, m.value))
    ...
}

implicit def numToValue[T : Numeric](v: T) = Value[T](v)
有没有办法让
someIntValue+double
这样的东西起作用,其中
someIntValue
Value[Int]
double
double

PS:很抱歉这个远不完美的标题。我非常感谢您对更好的措辞提出的建议…

您可以通过创建隐式运算符来实现这一点(需要大量的工作):

abstract class Arith[A,B,C] {
  def +(a: A, b: B): C
  def -(a: A, b: B): C
  def *(a: A, b: B): C
  def /(a: A, b: B): C
}
implicit object ArithIntLong extends Arith[Int,Long,Long] {
  def +(a: Int, b: Long) = a+b
  def -(a: Int, b: Long) = a-b
  def *(a: Int, b: Long) = a*b
  def /(a: Int, b: Long) = a/b
}
...
def f[A,B,C](a: A, b: B)(implicit arith: Arith[A,B,C]) = arith.*(a,b)


scala> f(5,10L)
res46: Long = 50

但是你真的需要做更多的事情,因为你需要一个a和B的数值等价物,不对称操作需要以两种方式定义。考虑到涉及到三种类型,专业化并不实际。

mhh。。。。这真的是一个没有更好解决方案的罕见问题吗?这个解决方案的另一个大问题是,我们实际上无法知道(因此也无法涵盖)符合
Numeric[t]
@soc的所有类型——这真的太糟糕了。问题在于,
Numeric
无法判断这三种类型的相对精度。你可以把
Arith
简单地做成一个从
a
B
C
的转换器,然后让
C
成为
数值的
,并把你所有的数学都当作
C
。这将减少样板文件,但您仍然需要编写隐式转换器。还有一些可能有用的方法。