Numeric
的实例本身不是数字,但它是提供操作来执行算术的对象。例如,Numeric[Int]
类型的对象num
可以添加两个整数像这样:num.plus(3, 5)
该操作的结果是整7.
对于整数,这是非常简单。但是,对于所有基本数字类型,都有一个隐式Numeric
的实例可用。如果你定义你自己的数字类型,你可以提供一个。
因此,您应该打开A
的范围,并添加一个类型为Numeric[A]
的隐式参数,并使用该参数进行计算。就像这样:
def **[A](l:List[A],m:List[A])(implicit num:Numeric[A])=l.zip(m).map({t=>num.times(t._1, t._2)})
当然,num.times(a,b)
看起来比a*b
那么优雅。在大多数情况下,人们可以忍受这一点。但是,您可以在Ops
类型的对象,它支持运营商包的价值a
,就像这样:
// given are: num:Numeric[A], a:A and b:A
val a_ops = num.mkNumericOps(a)
val product = a_ops * b
由于该方法mkNumericOps
声明implicit
,你也可以导入并含蓄地使用它:
// given are: num:Numeric[A], a:A and b:A
import num._
val product = a * b
我会在哪里把进口num._声明我的**功能的情况下? – user44242 2010-12-14 09:00:08
您需要在等号后面打开一个块。我没有测试这个,但我想它应该看起来像这样:'def ** [A](l:List [A],m:List [A])(implicit num:Numeric [A])= {import num._; l.zip(m).map({t => t._1 * t._2})}' - 尽管如此,我会努力去尝试。我不确定隐式包装Ops对象的创建是否会影响性能,或者是否会被编译器优化。 – Madoc 2010-12-14 09:04:56
我希望如果启用逃生分析,它应该进行优化,但没有保证。 – 2010-12-14 18:39:37