Сумма сбора Scala для работы с перегруженным дополнением - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь заставить перегруженный оператор сложения работать с методом 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;}

Я считаю, что это должно что-то делать с implicit s (как четко указано в сообщении об ошибке), но я не знаю, где его следует определить или добавить (в случае класса Probability, его объект comanion, или после sum?), или как это должно выглядеть.

1 Ответ

0 голосов
/ 03 сентября 2018

Метод 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] или если вы хотите получить в качестве вероятности результат, вы можете использовать уменьшение вместо суммы.

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

или reduOption, если список может быть пустым.

Относительно того, где вы можете определить свой Numeric[Probability], вы должны принять во внимание область действия имплицитов. Обычно определяется реализация по умолчанию для объекта-компаньона, но вы можете создать ее до суммирования, через импорт, или вы можете используйте это явно. Это зависит от того, что вам нужно.

...