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

Scala 如何使用数字[T]表示任何数字类型的零,scala,generics,type-inference,typeclass,zero,Scala,Generics,Type Inference,Typeclass,Zero,我有一段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]): Ma

我有一段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)) }
  }
我想写这样的东西(只写一次),其中零值自动转换为a
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)) }
  }
试一试

导入提供隐式转换
infixNumericOps

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

因此,我们不必像第一个示例中那样显式使用
Numeric.plus

@LuisMiguelMejíaSuárez是
import num.。
风格不受欢迎?我经常在宏中看到这种风格,例如,
import c.universe.\u
。不,这很好,我指的是当必须隐式地使用
调用隐式时,使用上下文边界没有任何价值。但这只是我自己的一种风格偏好,因此我只会使用一个隐式参数来命名它,并像您一样调用import。@LuisMiguelMejíaSuárez我找到了一个不错的理由,支持Philip Schwarz不命名implicits of,在这里它是这样说的“givens或implicits的要点是编译器将为您生成它们,那么您为什么要麻烦给它们命名呢?“有趣。然而,这张幻灯片在创建隐式而不是使用隐式时提到的更多,在这种情况下,我同意不必在Scala 3上命名它们会更好。现在,在方法/函数的上下文中。我确实认为,如果所有类型类都提供一个类似于
Monoid[T]
(并应用于companion)的召唤器,那么只使用上下文边界将是一个很好的论据。但是由于很多人没有这样的参数,而且
隐式的
对我来说太冗长了,所以我更喜欢只使用普通的隐式参数。
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)) }
}
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)) }
}
m1 ++ m2.map { case (k, v) => k -> (infixNumericOps(v) + m1.getOrElse(k, num.zero)) }