Как написать неявное числовое значение для кортежа

У меня есть сценарий, в котором я хотел бы вызвать sum для последовательности кортежей (Double, Double). В идеале я хотел бы сделать что-то вроде следующего:

implicit def toTupleNumeric[T](num: Numeric[T]) = new Numeric[(T, T)] {
    def plus(x: (T, T), y: (T, T)): (T, T) = (num.plus(x._1, y._1), num.plus(x._2, y._2))
    def minus(x: (T, T), y: (T, T)): (T, T) = (num.minus(x._1, y._1), num.minus(x._2, y._2))
    def times(x: (T, T), y: (T, T)): (T, T) = (num.times(x._1, y._1), num.times(x._2, y._2))
    def negate(x: (T, T)): (T, T) = (num.negate(x._1), num.negate(x._2))
    def fromInt(x: Int): (T, T) = (num.fromInt(x), num.fromInt(x))
    def toInt(x: (T, T)): Int = num.toInt(x._1) + num.toInt(x._2)
    def toLong(x: (T, T)): Long = num.toLong(x._1) + num.toLong(x._2)
    def toFloat(x: (T, T)): Float = num.toFloat(x._1) + num.toFloat(x._2)
    def toDouble(x: (T, T)): Double = num.toDouble(x._1) + num.toDouble(x._2)
    def compare(x: (T, T), y: (T, T)): Int = num.compare(x._1, y._1) match {
        case c if c == 0 => num.compare(x._2, y._2)
        case c => c
    }
}

Но когда я вызываю сумму:

val seq: Seq[(Double, Double)] = ...
val sum = seq.sum

Я получаю ошибку компилятора:

не удалось найти неявное значение для параметра num: Numeric[(Double, Двойной)]

Есть ли способ реализовать такое неявное?

Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
0
0
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы, кажется, путаете условное неявное

implicit def toTupleNumeric[T](implicit num: Numeric[T]): Numeric[(T, T)] = ...

С неявным преобразованием

implicit def toTupleNumeric[T](num: Numeric[T]): Numeric[(T, T)] = ...

В первом случае вы указываете, что тип данных (T, T) (также известный как scala.Tuple2[T, T]) является экземпляром класса типов Numeric при условии, что T является экземпляром класса типов. Это означает, что если есть имплицит типа Numeric[T], то существует имплицит типа Numeric[(T, T)]. В Scala 3 тип этого условного имплицита — Numeric[T] ?=> Numeric[(T, T)] (также известный как ContextFunction1[Numeric[T], Numeric[(T, T)]]).

С последним вы указываете, что тип данных Numeric[T] может использоваться там, где ожидается тип данных Numeric[(T, T)], и эта функция Numeric[T] => Numeric[(T, T)] (также известная как Function1[Numeric[T], Numeric[(T, T)]]) должна использоваться для такого преобразования автоматически.

Я думаю, вы имели в виду первое. Поэтому добавьте implicit к параметру (num: Numeric[T]), сделав его неявным параметром (implicit num: Numeric[T]). Тогда ваш код скомпилируется.

Вы можете освежить свое понимание имплицитов в Scala:

Понимание имплицитов в Scala

Чем полезны классы типов в Scala?

Неявное преобразование против класса типов

Как связать имплициты в Scala?

Почему неявное преобразование не рекомендуется в scala?

Кто-нибудь может объяснить мне неявные преобразования в Scala?

Scala — неявное преобразование в неявный аргумент

Неявное преобразование с неявным параметром

Https://docs.scala-lang.org/tour/implicit-parameters.html https://docs.scala-lang.org/tour/implicit-conversions.html

Https://docs.scala-lang.org/scala3/book/ca-contextual-abstractions-intro.html ...

Https://docs.scala-lang.org/scala3/reference/contextual/index.html ...

Вы также можете переписать свое определение, используя привязку к контексту (: Numeric), импортируя имплициты, методы расширения, также известные как синтаксис класса типов (.toInt, .+(...)), и материализатор класса типов (Numeric.apply[T]).

import Numeric.Implicits._

implicit def toTupleNumeric[T: Numeric]: Numeric[(T, T)] =
  new Numeric[(T, T)] {
    override def plus(x: (T, T), y: (T, T)): (T, T) = (x._1 + y._1, x._2 + y._2)
    override def minus(x: (T, T), y: (T, T)): (T, T) = (x._1 - y._1, x._2 - y._2)
    override def times(x: (T, T), y: (T, T)): (T, T) = (x._1 * y._1, x._2 * y._2)
    override def negate(x: (T, T)): (T, T) = (-x._1, -x._2)
    override def fromInt(x: Int): (T, T) = (Numeric[T].fromInt(x), Numeric[T].fromInt(x))
    override def toInt(x: (T, T)): Int = x._1.toInt + x._2.toInt
    override def toLong(x: (T, T)): Long = x._1.toLong + x._2.toLong
    override def toFloat(x: (T, T)): Float = x._1.toFloat + x._2.toFloat
    override def toDouble(x: (T, T)): Double = x._1.toDouble + x._2.toDouble
    override def compare(x: (T, T), y: (T, T)): Int = Numeric[T].compare(x._1, y._1) match {
      case c if c == 0 => Numeric[T].compare(x._2, y._2)
      case c => c
    }
    override def parseString(str: String): Option[(T, T)] = ???
  }

Что такое «привязка к контексту» в Scala?

Другие вопросы по теме