如何使用Numeric [T]表示任何数字类型的零

Mic*_*l K 3 generics scala type-inference zero typeclass

我有一段Scala代码,我想使其更加通用。我知道那是Numeric[T]存在的,但是我不确定如何使用它。

  def sumMaps[A](m1: Map[A, Long], m2: Map[A, Long]): Map[A, Long] = {
    m1 ++ m2.map { case (k, v) => k -> (v + m1.getOrElse(k, 0L)) }
  }

  def sumMaps[A](m1: Map[A, Int], m2: Map[A, Int]): Map[A, Int] = {
    m1 ++ m2.map { case (k, v) => k -> (v + m1.getOrElse(k, 0)) }
  }

  def sumMaps[A](m1: Map[A, Double], m2: Map[A, Double]): Map[A, Double] = {
    m1 ++ m2.map { case (k, v) => k -> (v + m1.getOrElse(k, 0)) }
  }
Run Code Online (Sandbox Code Playgroud)

我想写这样的东西(仅一次),其中零值会自动转换为B类型。

  def sumMaps[A, B: Numeric[?]](m1: Map[A, B], m2: Map[A, B]): Map[A, B] = {
    m1 ++ m2.map { case (k, v) => k -> (v + m1.getOrElse(k, 0)) }
  }
Run Code Online (Sandbox Code Playgroud)

Mar*_*lic 5

尝试

def sumMaps[A, B](m1: Map[A, B], m2: Map[A, B])(implicit num: Numeric[B]): Map[A, B] = {
  m1 ++ m2.map { case (k, v) => k -> num.plus(v, m1.getOrElse(k, num.zero)) }
}
Run Code Online (Sandbox Code Playgroud)

要么

import Numeric.Implicits._
def sumMaps[A, B](m1: Map[A, B], m2: Map[A, B])(implicit num: Numeric[B]): Map[A, B] = {
  m1 ++ m2.map { case (k, v) => k -> (v + m1.getOrElse(k, num.zero)) }
}
Run Code Online (Sandbox Code Playgroud)

要么

def sumMaps[A, B: Numeric](m1: Map[A, B], m2: Map[A, B]): Map[A, B] = {
  val num = implicitly[Numeric[B]]
  import num._
  m1 ++ m2.map { case (k, v) => k -> (v + m1.getOrElse(k, zero)) }
}
Run Code Online (Sandbox Code Playgroud)

导入提供隐式转换 infixNumericOps

m1 ++ m2.map { case (k, v) => k -> (infixNumericOps(v) + m1.getOrElse(k, num.zero)) }
Run Code Online (Sandbox Code Playgroud)

因此我们不必Numeric.plus在第一个示例中显式使用like。

  • 不,那很好,我指的是当必须使用“隐式”来调用隐式时,使用上下文边界没有任何价值。但这只是我自己的样式首选项,因此,我将使用隐式参数对其进行命名,然后像您一样调用导入。 (2认同)