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

问题描述 投票:2回答:1

我试图使用集合的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;}

我认为这必须与implicits做一些事情(正如错误信息明确指出的那样),但我不知道应该在哪里定义或添加(在类Probability,它的人体对象,或者在sum之后?),或者如何应该看。

scala collections sum operator-overloading implicit
1个回答
3
投票

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]实例,或者如果您希望将Probability作为结果,则可以使用reduce而不是sum。

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

如果列表可能为空,则为reduceOption。

关于你可以定义Numeric[Probability]的位置,你必须考虑implicits的范围。在对象伴侣上定义默认实现是很常见的,但你可以在求和之前通过导入创建它,或者你可以明确地使用它。这取决于你需要什么。

© www.soinside.com 2019 - 2024. All rights reserved.