Using implicit conversions to turn Int
into Complex
as mentioned before will do the job.
Here's a working solution which puts it all together to complement Ivan's answer:
import scala.language.implicitConversions
class Complex(val real:Double, val imaginary:Double){
def +(other:Complex) = new Complex(real+other.real, imaginary+other.imaginary)
//def +(other:Double) = new Complex(real+other,imaginary) // Not needed now
def ==(other:Complex) = real==other.real && imaginary==other.imaginary
override def toString: String = s"$real + ${imaginary}i"
}
object Complex {
implicit def intToComplex(real: Int): Complex = doubleToComplex(real.toDouble)
implicit def doubleToComplex(real: Double): Complex = Complex(real, 0)
implicit def apply(real: Double, imaginary: Double): Complex = new Complex(real, imaginary)
implicit def apply(tuple: (Double, Double)): Complex = Complex(tuple._1, tuple._2)
def main(args: Array[String]) {
val c1 = Complex(1, 2)
println(s"c1: $c1")
val c2: Complex = (3.4, 4.2) // Implicitly convert a 2-tuple
println(s"c2: $c2")
val c3 = 2 + c1
println(s"c3: $c3")
val c4 = c1 + 2 // The 2 is implicitly converted then complex addition is used
println(s"c4: $c4")
}
}
Some notes:
- tested under 2.10.3. Depending on your version you might need the import at the top of the file.
- once you have implicit conversions, you don't actually need the original + method which takes an
Int
input (hence I commented it out). Examplec4
proves this. - consider making your class generic - that is instead of using
Double
, just use some numerical type which is broad enough for your needs. The concept of a complex number is actually completely decoupled from the field/ring/group it extends. For example, if your underlying type has multiplication and addition, you can define multiplication and addition for complex numbers too. - I added an implicit conversion for the
Tuple2[Double, Double]
class - just because it seemed cool. Examplec2
demonstrates it. - similarly I added
apply
methods. Consider addingunapply
methods to make it morecase
friendly. - I renamed your constructor arguments simply to make the
toString
method less confusing (so you don't have ${i}i) - (side track) you're
==
method is comparing typeDouble
, notInt
, so you'll get all the usual frustration and unexpected behaviour with floating point comparisons