Sidd
Sidd

Reputation: 39

Type mismatch error when type is not defined in abstract class

I am new to Scala and got stuck with a compiler error from below code. I am trying to implement a Natural number class which represents +ve integers. I am facing problem while defining the + operator which should follow, def + (that: Nat): Nat but I don't define this in abstract class I get below error. But it goes away once it is defined in the abstract class.

[error] D:\Scala\NatuarlNum\src\main\scala\NatuarlNum.scala:31:46: type mismatch;
[error]  found   : Nat
[error]  required: String
[error]   def + (that: Nat): Nat = new Succ(previous.+(that))

I am not able to understand why it says required is "String" instead of "Nat". even when the function declaration is present just before the definition.

Here is the code:

abstract class Nat {
  def isZero: Boolean
  def predecessor: Nat
  def successor: Nat
  //def + (that: Nat): Nat  // By uncommentng this line the error will go away
  //def - (that: Nat): Nat
  override def toString: String = {
    if (this.isZero) {
      "0"
    } else {
      "{" + this.predecessor.toString + "}"
    }
  }
}

object Zero extends Nat {
  def isZero = true
  def predecessor = throw new Error("0.predecessor")
  def successor: Nat = new Succ(this)
  def + (that: Nat): Nat = that
}

class Succ(previous: Nat) extends Nat {
  def isZero = false
  def predecessor = previous
  def successor: Nat = new Succ(this)
  def + (that: Nat): Nat = new Succ(previous.+(that))  // The error is from this line
}

object NatuarlNum {
  def main(args: Array[String]): Unit = {
    val zero = Zero
    val one = new Succ(zero)
    val two = new Succ(one)
    val three = new Succ(new Succ(new Succ(Zero)))

    println("0 = " + zero)
    println("1 = " + one)
    println("2 = " + two)
    println("3 = " + three)

    println("0 + 2 = " + (zero + two))
    println("2 + 2 = " + (two + two))   

  }
}

Without the + operator my code compiles and gives result like this:

0 = 0
1 = {0}
2 = {{0}}
3 = {{{0}}}
0 + 2 = {{0}}

Upvotes: 0

Views: 83

Answers (1)

Vüsal
Vüsal

Reputation: 2706

Well, you gave an answer to your question in your code.

  //def + (that: Nat): Nat  // By uncommentng this line the error will go away
  //def - (that: Nat): Nat

The problem is,

def + (that: Nat): Nat = new Succ(previous.+(that))

previous is of type Nat, which doesn't have + operator override.

If you uncomment the definition for operators in Nat - it will work.

The default implementation of + operator takes String as a parameter, which explains the error message you get, see any2stringadd for more info and there is a ticket to remove implicit + operator definition.

From compiler warning:

Predef is deprecated (since 2.13.0): Implicit injection of + is deprecated. Convert to String to call +

Upvotes: 3

Related Questions