8
votes

While experimenting with some stuff on the REPL, I got to a point where I needed something like this:

scala> class A(x:Int) { println(x); def ==(a:A) : Boolean = { this.x == a.x; } }

Just a simple class with an "==" operator.

Why doesn't it work???

Here's the result:

:10: error: type mismatch;
 found   : A
 required: ?{val x: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
 and method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
 are possible conversion functions from A to ?{val x: ?}
       class A(x:Int) { println(x); def ==(a:A) : Boolean = { this.x == a.x; } }
                                                                        ^

This is scala 2.8 RC1.

Thanks

2

2 Answers

16
votes

You have to define the equals(other:Any):Boolean function, then Scala gives you == for free, defined as

class Any{
  final def == (that:Any):Boolean =
    if (null eq this) {null eq that} else {this equals that}
}

See chapter 28 (Object Equality) of Programming in Scala for more on how to write the equals function so that it's really an equivalence relation.

Moreover, the parameter x that you pass to your class isn't stored as a field. You need to change it to class A(val x:Int) ..., and then it will have an accessor that you can use to access a.x in the equals operator.

7
votes

The error message is a little confusing because of coincidence with some code in Predef. But what's really going on here is that you're trying to call the x method on your A class, but no method with that name is defined.

Try:

class A(val x: Int) { println(x); def ==(a: A): Boolean = { this.x == a.x } }

instead. This syntax makes x a member of A, complete with the usual accessor method.

As Ken Bloom mentioned, however, it's a good idea to override equals instead of ==.