Symmetry of equality

I have a class which wraps an Int:

class Constant(val i: Int) {
  def equals(other: Any) = other match {
    case that: Constant => this.i == that.i
    case that: Int => this.i == that
    case _ => false
  }
} 

new Constant(4) == 4 is true but 4 == Constant(4) is false, breaking symmetry.
Is there any way around this, given Int is built-in and has its own equals method?
I presume implicits will not be called since there is already a def == (that: Any)
method on Int?

If you insist on using == operator then you’ll need to wait for Dotty / Scala 3: https://dotty.epfl.ch/docs/reference/contextual/multiversal-equality.html
If you want something that works in Scala 2, then you need to use different operator, e.g. === in a typeclass.

Universal equality is very tricky, as you have observed. I have found that it’s simplest to treat equality as a property defined only among elements of a single type (as with cats.Eq) and treat conversions between isomorphic types as an orthogonal issue.

1 Like

usuall you don’t need any fancy staff like typeclass
you can just use implicits, and 4 automatic convert to Constant(4), but you need to use different equalty operator
for excample:

implicit class Constant(val i: Int) {
  def ===(other: Constant) = other.i == i
}

10 === new Constant(10) // true
new Constant(10) === 10 // true
10 === 10 // true