More on generic Scala functions

余生长醉 提交于 2019-12-03 09:48:18
Dylan

You are using the Int literal 2 but scala is expecting the Numeric type A. The Scala Numeric API has a utility function- def fromInt(x:Int): T. This is what you want to use, so replace your usage of 2 with numeric.fromInt(2)

def doubleUs[A](x:A,y:A)(implicit numeric: Numeric[A]): A =
  numeric.plus (numeric.times (x, numeric.fromInt (2)), numeric.times (y, numeric.fromInt (2)))

Also, since a Numeric instance defines an implicit conversion to an Ops, you can import numeric._ and then say x * fromInt(2) + y * fromInt(2).

In addition to what @Dylan said, you can make it look a little less tedious by importing into scope the contents of Numeric implicit as shown below:

scala> def doubleUs[N](x: N, y: N)(implicit ev: Numeric[N]) = {
     |   import ev._
     |   x * fromInt(2) + y * fromInt(2)
     | }
doubleUs: [N](x: N, y: N)(implicit ev: Numeric[N])N

scala> doubleUs(3, 4)
res9: Int = 14

scala> doubleUs(8.9, 1.2)
res10: Double = 20.2
Didier Dupont

You need some implicits in scope:

def doubleUs[A](x: A, y: A)(implicit num: Numeric[A]) = {
  import num._
  implicit def fromInt(i: Int) = num.fromInt(i)
  x * 2 + y * 2
}

Dylan essentially answered, but for what it's worth, let me suggest to use the context bound syntax instead of the implicit argument (both are equivalent, and the former is automatically rewritten into the latter by the compiler).

def doubleUs[A : Numeric](x : A, y : A) : A = {
  val num = implicitly[Numeric[A]]
  import num.{plus,times,fromInt}
  plus(times(x, fromInt(2)), times(y, fromInt(2)))
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!