Scala compiler not recognizing a view bound

前端 未结 2 1198
太阳男子
太阳男子 2021-01-07 02:01

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

相关标签:
2条回答
  • 2021-01-07 02:20

    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
    
    0 讨论(0)
  • 2021-01-07 02:36

    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 讨论(0)
提交回复
热议问题