Scala编译器无法识别视图绑定

时间:2010-12-14 07:46:04

标签: scala

我已经尝试过这行代码

def **[A <% Numeric[A]](l:List[A],m:List[A])=l.zip(m).map({t=>t._1*t._2})

然而,在编译时,我收到此错误

error: value * is not a member of type parameter A
def **[A <% Numeric[A]](l:List[A],m:List[A])=l.zip(m).map({t=>t._1*t._2})

当我查看数字特征的来源时,我看到定义了* op。

我做错了什么?

2 个答案:

答案 0 :(得分:6)

Numeric的实例本身不是数字,但它是一个提供算术运算的对象。例如,类型为num的对象Numeric[Int]可以添加两个这样的整数: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优雅。在大多数情况下,人们可以忍受这种情况。但是,您可以将值a包装在支持运算符的Ops类型的对象中,如下所示:

// 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

答案 1 :(得分:2)

您也可以使用context bound解决此问题。使用this answer中的context方法,您可以写:

def **[A : Numeric](l:List[A],m:List[A]) =
   l zip m map { t => context[A]().times(t._1, t._2) }

def **[A : Numeric](l:List[A],m:List[A]) = {
   val num = context[A]()
   import num._
   l zip m map { t => t._1 * t._2 }
}