6

数値に変換できるものなら何でもパラメータ化できるクラスを作成しました

class Complex[T <% Numeric[T]] (val real : T, val imag : T) {
   //... complex number methods ...
}

次に、コードの他の場所で試してみます。

var myComplex = new Complex(0, 1)

(驚くべきことに)IntとNumeric [Int]の間、またはIntとIntegral [Int]の間でさえ暗黙の変換がないため、これによりコンパイルエラーが発生します。

私は何かが足りないのですか?私が見ていないところに暗黙の変換がありますか?

Numeric.scalaで定義されたIntIsIntegralと呼ばれる暗黙のオブジェクトがあります。これを使用して、独自の暗黙的な変換メソッドを作成してみました。

def implicit intToNumericInt(val i : Int)(implicit n : IntIsIntegral) = n.fromInt(i)

これが必要であることに驚いています。とにかく、.fromIntメソッドへの無限再帰につながるようです。

私は基本的なものが欠けていると確信しています(あなたが言うことができるように、私はScalaに不慣れです)ので、正しい方向へのポイントをいただければ幸いです。

例からわかるように、私は任意の数値タイプを受け入れて機能できる複素数の実装を機能させようとしています。これをscalala(線形代数)プロジェクトに貢献したいと思っています。続いて、行列内の要素(主に+演算子と*演算子のみ)の責任と、複素数のサポートを行列操作ライブラリに後付けする特性を紹介します。

4

2 に答える 2

10

あなたはそれを間違って使用しています。正しい使用法は次のとおりです。

class Complex[T](val real : T, val imag : T)(implicit num: Numeric[T]) {
   import num._ // make implicit conversions available
   //... complex number methods ...
}

Orderedとの間と同じ違いOrderingです。Ordered[T]インスタンスはと比較できますが、はいくつかのを比較するメソッドを提供しTます。Ordering[T]T

于 2010-10-27T12:52:26.313 に答える
2

Scala 2.8では、次のように書くこともできます

class Complex[T: Numeric] (val real : T, val imag : T) {

  def +(that: Complex[T]) = {
    val r = implicitly[Numeric[T]].plus(this.real, that.real)
    val i = implicitly[Numeric[T]].plus(this.imag, that.imag)
    new Complex(r, i)
  }

}

この構文は確かに少し密度が高いですが、次のように読みやすくすることができます。

class Complex[T: Numeric] (val real : T, val imag : T) {
  val num = implicitly[Numeric[T]]

  def +(that: Complex[T]) = {
    new Complex(num.plus(this.real, that.real), num.plus(this.imag, that.imag))
  }

}

宣言は、前のソリューションへのコメントに記載されているclass C[T: M]( ... ) { val x = implicitly[M[T]]ものと同等のように思われます。class C[T]( ... )(implicit x: M[T]) { import x._コンパイル方法に違いがあるため、これは単なる構文糖衣ではありません。たとえば、最初のケースxではメソッドであり、2番目のケースではフィールドです。

于 2010-10-27T14:10:41.750 に答える