开发者

Scala compiler not recognizing a view bound

I've tried this line of code

def **[A <% Numeric[A]](l:开发者_运维技巧List[A],m:List[A])=l.zip(m).map({t=>t._1*t._2})

However on compilation, I get this error

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})

When I look at the source for the Numeric trait, I see a * op defined.

What am I doing wrong?


The instance of Numeric is not a number itself, but it is an object that offers operations to do the arithmetic. For example, an object num of type Numeric[Int] can add two integers like this: num.plus(3, 5) The result of this operation is the integer 7.

For integers, this is very trivial. However, for all basic numerical types, there is one implicit instance of Numeric available. And if you define your own numeric types, you can provide one.

Therefore, you should leave the bounds for A open and add an implicit parameter of type Numeric[A], with which you do the calculations. Like this:

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

Of course, num.times(a,b) looks less elegant than a*b. In most of the cases, one can live with that. However, you can wrap the value a in an object of type Ops that supports operators, like this:

// given are: num:Numeric[A], a:A and b:A
val a_ops = num.mkNumericOps(a)
val product = a_ops * b

Since the method mkNumericOps is declared implicit, you can also import it and use it implicitly:

// given are: num:Numeric[A], a:A and b:A
import num._
val product = a * b


You can also solve this with a context bound. Using the context method from this answer, you can write:

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

or

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜