3

私は正常にコンパイルされたいくつかの 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].
4

1 に答える 1

5

Numeric型クラスです。つまり、この方法でインスタンスを操作するのNumeric[Double]ではなく、数値操作を実行する方法を指定する単一の暗黙的なNumeric[Double]スコープがありますDouble(の関連する説明については、ここでの私の回答Orderingを参照してください)。

Numeric[T]したがって、ではなく、暗黙的なを探していますT => Numeric[T]。そして幸いなことに、Doubleのスコープ内にそれらの1つがあるので、次のように書くことができます。

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

または:

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

最初の「コンテキストバウンド」は、2番目の暗黙の引数の単なる構文糖衣です。

于 2012-12-02T15:55:16.627 に答える