Scala 集合总和可与重载加法一起使用

标签 scala collections sum operator-overloading implicit

我正在尝试使重载的加法运算符与集合的 sum 方法一起使用。例如,对于

final case class Probability(val value: Double) {
  def +(that: Probability): Probability =
    Probability(this.value + that.value)
}

List(Probability(0.4), Probability(0.3)).sum

我收到以下错误消息:

Error:(6, 109) could not find implicit value for parameter num:
  Numeric[A$A42.this.Probability]
def get$$instance$$res0 = /* ###worksheet### generated $$end$$ */
  List(Probability(0.4), Probability(0.3)).sum;}

Error:(6, 109) not enough arguments for method sum: 
  (implicit num: Numeric[A$A42.this.Probability])A$A42.this.Probability.
Unspecified value parameter num.
def get$$instance$$res0 = /* ###worksheet### generated $$end$$ */
   List(Probability(0.4), Probability(0.3)).sum;}

我认为这与隐式有关(正如错误消息明确指出的那样),但我不知道应该在哪里定义或添加它(在类 的情况下)概率,它的伴生对象,还是在sum之后?),或者它应该是什么样子。

最佳答案

Sum 方法与类型类 Numeric[T] 一起使用,因此如果您想通过自己的“数字类型”调用 sum,则需要定义 Numeric[Probability] 的实例。

放置自定义类型类定义的最佳位置是对象伴生。

object Probability {

  implicit val probabilityNumberic = new Numeric[Probability] {
    def plus(x: Probability, y: Probability): Probability = ???
    def minus(x: Probability, y: Probability): Probability = ???
    def times(x: Probability, y: Probability): Probability = ???
    def negate(x: Probability): Probability = ???
    def fromInt(x: Int): Probability = ???
    def toInt(x: Probability): Int = ???
    def toLong(x: Probability): Long = ???
    def toFloat(x: Probability): Float = ???
    def toDouble(x: Probability): Double = ???
    def compare(x: Probability, y: Probability): Int = ???
  }

}

或者,如果您不想定义 Numeric[T] 实例或者想要概率作为结果,则可以使用 reduce 而不是 sum。

List(Probability(0.4), Probability(0.3)).reduce(_ + _)

或者如果列表可以为空则使用reduceOption。

关于在哪里定义Numeric[Probability],您必须考虑隐式的范围。在对象伴生上定义默认实现是很常见的,但您可以在 sum 调用之前创建它,通过导入,或者您可以显式使用它。这取决于您的需要。

关于Scala 集合总和可与重载加法一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52143784/

相关文章:

scala - 尝试/捕捉 : Object Exception is not a value

java - 这段代码有什么作用? (Java 集合)

java - 将数组转换为列表

java - 如何向我的 Map<Integer>、List<String>> 添加一个值?

sql - 累计计数

MySQL 并集和平均值

scala - 如何让 sbt 获取发布到我的 bintray 存储库的存储库?

Scala 序号方法调用别名

java - AKKA:Actor 路由器消息持久化

php - 在 MongoDB 中求和 "column"