0

When I was playing with the Scala, I couldn't figure out something. Maybe I am doing completely wrong.

I was trying with Rational Example and Complex Example but I couldn't find a way to use operations like R*3/5 and 1/2*R

here is the complex numbers example I am working on

class Complex(val real : Int, val img : Int){

  def this(real: Int) = this(real, 0)

  def *(that : Complex) = {
    val realPart = this.real * that.real + -(this.img * that.img)
    val imgPart = this.real * that.img + this.img * that.real
    new Complex(realPart, imgPart)
  }

  override def toString = this.real  + "+" + this.img + "i"

}

object Complex {
  def apply(real : Int, img : Int) = new Complex(real, img)
  def apply(real : Int) = new Complex(real)
}

object ComplexNumbers {

  def main(args: Array[String]) {

    import ComplexConversions._
    println(Complex(1,2)) // 1+2i
    println(I*2) //0+2i
    println(2*I) //0+2i
  }
}

Well I have tried to create an object I

object I{
  def apply() = new Complex(0,1)  

  def *(that : Complex) = {
    val realPart = 0 * that.real + -(1 * that.img)
    val imgPart = 0 * that.img + 1 * that.real
    new Complex(realPart, imgPart)
  }
}

but it did work for the I*2. but I have problems for 2*I. How can I reach the result that I want?

2 Answers 2

4

When you call "I * 2", scala looks for a method named "*" on the class of I, and finds it.

When you call "2 * I", scala looks for a method named "*" on the class of 2 (which is Int), and cannot find one.

Even though Int is defined externally, you can add this method to it in Scala via the "implicit conversion" mechanism. This is covered briefly in the "implicits" example and in more detail elsewhere, e.g. here

Try adding some code like the following to your "Complex" object:

object Complex {
  implicit class IntOps(x: Int) {
    def *(y: Complex) = y * x
  }
}

You'll also need to declare I as a val, rather than an Object for this to work:

val I = Complex(0, 1)

(or add an implicit method like class Complex { def *(i: I) = ... }, but that's much uglier)

(I assume by Complex Example, you mean this?)


Working code:

class Complex(val real : Int, val img : Int){

  def this(real: Int) = this(real, 0)

  def *(that : Complex) = {
    val realPart = this.real * that.real + -(this.img * that.img)
    val imgPart = this.real * that.img + this.img * that.real
    new Complex(realPart, imgPart)
  }

  override def toString = this.real  + "+" + this.img + "i"

}

object Complex {
  def apply(real : Int, img : Int) = new Complex(real, img)
  def apply(real : Int) = new Complex(real)

  val I = Complex(0, 1)

  implicit def toComplex(x: Int): Complex = new Complex(x)
}

object ComplexNumbers {

  def main(args: Array[String]) {

    import Complex._

    println(Complex(1,2)) // 1+2i
    println(I*2) //0+2i
    println(2*I) //0+2i
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I understand the lookup for method part. I added the code but I still get type mismatch error because I doesn't behave like Complex. (it says I.type)?
The problem is that by declaring "I" as an "object", it gets its own singleton class, which is a different class to Complex. You haven't added "extends Complex" to "I", so it isn't even a complex number. I have added a fully working example to my answer.
2

If you want to be able to use 2*I, you will need to add a new * override for the Int class (since * is really a method of the class Int, meaning 2*I is really 2.*(I)).

You can accomplish this with an implicit class:

scala> case class myInt(i: Int){
     | def mult(that: Int): myInt = myInt(that * i)
     | }
defined class myInt

scala> implicit class intOverride(i: Int){
     |     def *(that: myInt): myInt = that.mult(i)
     | }
defined class intOverride

scala> val a = myInt(2)
a: myInt = myInt(2)

scala> 2 * a
res1: myInt = myInt(4)

2 Comments

The same solution but now I stuck again because type of I is not Complex. When I try create it as val I = new Complex(0,1). It becomes private and I can't reach it from the main
In my case the scope of the * override is outside of the Complex class so you should have access from any object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.