構造型はJVM上で非常に高価なので、避けてください。これは、Numeric
のみがDouble
としてエンコードされる可能性があることを意味します。 ScalaはNumeric
typeclassを、いわゆる "数値型"で一般的な操作を定義する方法として提供しています。したがって、あなたが提案しているものを実際に使用する必要はありません。
def fun1[T](seq: Seq[T])(ev: Numeric[T]): Double = {
val q2 = seq map ev.toDouble
val n = q2.size.toDouble
q2.sum/n
}
あなたが望むすべてが数字上の汎用であるためにあなたの操作であればあなたは本当にそれより創造的な取得する必要はありません。それ以外の場合は、独自の型クラスを実装する必要があります。今
trait Converter[T] {
def toDouble(source: T): Double
}
object Converter {
implicit def numericConvert[T : Numeric]: Converter[T] = new Converter[T] { def toDouble(source: T): Double = implicitly[Numeric[T]].toDouble(source)}
implicit object StringConverter extends Converter[String] = ...
}
Numeric
に基づく単純なアプローチを使用するには、簡単なヘルパーを定義することができます。
object Helper {
implicit class ColOps[
M[X] <: TraversableOnce[X],
T
](val col: M[T])(implicit ev: Numeric[T]) {
def average: Double = {
val q2 = col map ev.toDouble
val n = q2.size.toDouble
q2.sum/n
}
}
}
今、すべてを行う必要がある。我々はあまりにも一般的なコレクション型の上に抽象できるので
import Helper._
List(1, 2, 3).average
Seq(1, 2, 3).average
Set(5F, 2F, 3F).average
これは、もう少しクールです。
'{def foo:Foo}'は 'AnyRef {def foo:Foo}'の略です。 'AnyRef'以外のものが必要な場合は、明示的に名前を付ける必要があります。 –
@sheunis「動作しているように見える」というのは、基本的に 'AnyRef'にはプリミティブ型が含まれず、' AnyVal'には基本的な型が含まれていないということです。 – flavian
@flavianありがとう、私は同意します。私は編集をしました。 – sheunis