Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Где неявные преобразования между Numeric и Double определены в Scala 2.9

Автор вопроса: richjОтветов: 1

Я работал над кодом scala, который компилировался нормально, но каким-то образом я нарушил неявные преобразования и не могу понять, что я сделал не так. Сводя это к очень простому случаю, этот код не компилируется, и причина, по-видимому, в том, что я не импортирую неявные преобразования между Double и Numeric[Double]:

import scala.math.Numeric
import scala.math.Numeric._
import scala.math.Numeric.Implicits._
import Ordering.Implicits._

object ImplicitNumericConversions {
  val v: Numeric[Double] = 3.0
}

Я могу исправить это достаточно легко, предоставив свою собственную функцию:

import scala.math.Numeric

object ImplicitNumericConversions {
  def convertDoubleToNumeric(d: Double)(implicit num: Numeric[Double]): Numeric[Double] = num

  val v: Numeric[Double] = convertDoubleToNumeric(3.0)
}

Если я сделаю функцию преобразования неявной, я получу то, что ищу:

import scala.math.Numeric

object ImplicitNumericConversions {

  implicit def convertDoubleToNumeric(d: Double)(implicit num: Numeric[Double]): Numeric[Double] = num

  val v: Numeric[Double] = 3.0
}

... но почему импорт из scala.math.Numeric не делает этого за меня?

Фактическая проблема, над которой я работаю, выглядит так:

class NumericRange[T <% Numeric[T]](val lower: T, val upper: T) { ... }

object NumericRange {

  def apply[T](lower: T, upper: T)(implicit num: Numeric[T]) = {
    import num._
    new NumericRange[T](lower, upper)
  }
}

... где строка, создающая новый NumericRange, не компилируется с этими ошибками:

Multiple markers at this line
    - No implicit view available from T => scala.math.Numeric[T].
    - not enough arguments for constructor NumericRange: (implicit evidence$1: T => scala.math.Numeric[T])org.reductio.rtree.NumericRange[T]. Unspecified value parameter
     evidence$1.
    - not enough arguments for constructor NumericRange: (implicit evidence$1: T => scala.math.Numeric[T])org.reductio.rtree.NumericRange[T]. Unspecified value parameter
     evidence$1.
    - No implicit view available from T => scala.math.Numeric[T].

scalanumericimplicit-conversion

Ответы

Ответ 1 · рейтинг 5 · Travis Brown

Numeric - это класс типов, что означает, что вы не работаете с экземплярами Numeric[Double] таким образом. , а скорее у вас есть один неявный Numeric[Double] в области видимости, который указывает, как выполнять числовые операции с Double (см. мой ответ здесь для связанного обсуждения Ordering).

Итак, вы ищете неявный Numeric[T], а не T => Numeric[T]. И, к счастью, есть один из тех, Double, так что вы можете просто написать:

class NumericRange[T: Numeric](val lower: T, val upper: T) { ... }

Or:

class NumericRange[T](val lower: T, val upper: T)(implicit
  ev: Numeric[T]
) { ... }

"Контекстная привязка" в первом - это просто синтаксический сахар для неявного аргумента во втором.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы