2

私は現在 Scala プログラミング言語を学んでおり (ちなみにそれが大好きです)、最近暗黙の変換を発見しました。だから私は自分のクラス Complex とそのコンパニオン オブジェクトを持っています。そして、私のコンパニオンオブジェクトでは、これらの暗黙的な変換が必要です:

    implicit def convertToComplex(x: Double) = new Complex(x, 0);
    implicit def convertToComplex(x: Int) = new Complex(x, 0);
    implicit def convertToComplex(x: Float) = new Complex(x, 0);
    implicit def convertToComplex(x: Short) = new Complex(x, 0);
    implicit def convertToComplex(x: Long) = new Complex(x, 0);

+、-、* および / のオーバーロードで複素数クラスを肥大化させないために、数値型を追加します。

だから私の質問は:

ある種の構文糖衣を使って暗黙的な変換を記述するより短い方法はありますか? (つまり、すべての過負荷がないことを意味します...)

前もって感謝します。

4

3 に答える 3

4

You could do something like this

object ConvertComplex {
  case class Complex[T: Numeric](x: T, y: Int) {

    val nX = implicitly[Numeric[T]]

    def doSomething = nX.toInt(x) * y
    def doSomethingElse = nX.plus(x, nX.fromInt(y))
  }

  object Complex {
    implicit def convertToComplect[T: Numeric](x: T) = Complex(x, 0)
  }

}

And the test results:

def doSomething[T: Numeric](x: Complex[T]) = x.doSomething
def doSomethingElse[T: Numeric](x: Complex[T]) = x.doSomething

val double = 1: Double    //> double  : Double = 1.0
val int = 1: Int          //> int  : Int = 1
val float = 1: Float      //> float  : Float = 1.0
val short = 1: Short      //> short  : Short = 1
val long = 1: Long        //> long  : Long = 1

doSomething(double)       //> res0: Int = 0
doSomething(int)          //> res1: Int = 0
doSomething(float)        //> res2: Int = 0
doSomething(short)        //> res3: Int = 0
doSomething(long)         //> res4: Int = 0

doSomethingElse(double)   //> res5: Double = 1.0
doSomethingElse(int)      //> res6: Int = 1
doSomethingElse(float)    //> res7: Float = 1.0
doSomethingElse(short)    //> res8: Short = 1
doSomethingElse(long)     //> res9: Long = 1
于 2013-03-07T23:15:38.467 に答える
3

methodで必要な場合でIntegralはなく、必要です。NumericComplex/

ほぼ完成したソリューションを次に示します。

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.math.Integral

class Complex[T: Integral](val real: T, val imag: T) {
  import Integral.Implicits._
  def +(that: Complex[T]) = Complex(real+that.real, imag+that.imag)
  def -(that: Complex[T]) = Complex(real-that.real, imag-that.imag)
  def *(that: Complex[T]) = Complex(real*that.real - imag*that.imag, real*that.imag+imag*that.real)
  def /(that: Complex[T]) = {
    val d = that.real*that.real + that.imag*that.imag
    Complex((real*that.real + imag*that.imag)/d, (-real*that.imag+imag*that.real)/d)
  }
  override def toString: String = imag.signum match {
    case 1  => "" + real + "+" + imag +"i"
    case -1 => "" + real + "" + imag + "i"
    case _  => "" + real
  }
}

object Complex {
  import Integral.Implicits._
  def apply[T: Integral](real: T, imag: T): Complex[T] = new Complex[T](real, imag)
  object i extends Complex[Byte](0.toByte, 1.toByte)
  implicit class Real2Imag[T](val imag: T) {
    def *(v: i.type)(implicit ig: Integral[T]) = Complex(ig.zero, imag)
  }
  implicit def promote[U, V](c: Complex[U])(implicit ev: U => V, il: Integral[V]) =
    Complex(ev(c.real), ev(c.imag))
  implicit def real2complex[T: Integral](real: T) = Complex(real, implicitly[Integral[T]].zero)
  implicit val doubleIsIntegral = scala.math.Numeric.DoubleAsIfIntegral
}

// Exiting paste mode, now interpreting.

warning: there were 2 feature warnings; re-run with -feature for details
import scala.math.Integral
defined class Complex
defined object Complex

scala> import Complex._
import Complex._

scala> val c1 = 3 + 4*i
c1: Complex[Int] = 3+4i

scala> val c2 = 3.0 + 4.0*i
c2: Complex[Double] = 3.0+4.0i

scala> val c3 = c1/c2
c3: Complex[Double] = 1.0

scala> val c4 = 3 - 4*i
c4: Complex[Int] = 3-4i

scala> val c5 = c2*c4
c5: Complex[Double] = 25.0

メソッドを次のように記述できますpow(生成方法に注意してくださいComplex)。

  def pow(n: Int): Complex[T] = {
    val one = Complex[T](implicitly[Integral[T]].one, implicitly[Integral[T]].zero)
    Iterator.iterate(one)(_*this).drop(n).next
  }

scala> i.pow(2)
res5: Complex[Byte] = -1

scala> i.pow(10)
res6: Complex[Byte] = -1

scala> (1+1*i).pow(4)
res7: Complex[Int] = -4

scala> (1+1*i).pow(5)
res8: Complex[Int] = -4-4i
于 2013-03-08T01:07:29.777 に答える
0

はいあります。ComplexクラスにはDoubleパラメーターがあると思います。その後、暗黙的な変換を一発で書くことができます。

implicit def doubleToComplex[T <% Double](x: T): Complex = new Complex(x, 0)
于 2013-03-08T20:57:06.220 に答える