Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why has Scala no type-safe equals method?

Since the inventors highlight Scala's type-safety I don't understand the absence of an equals method on objects (at least from case classes) that allows to check the equality only on objects with same type. I'd wish a method === that implement this behavior per default. Of course its necessary for Java interoperability to have a method that works with Any type but in many cases I want to check only the equality between objects of same type.

Why do I need it?

For example I have two case classes and create objects from it

  case class Pos(x: Int, y: Int)
  case class Cube(pos: Pos)

  val startPos = new Pos(0, 0)
  val cubeOnStart = new Cube(startPos)

and later I need to check the positions several times and write accidentally

  if (startPos == cubeOnStart) {
    // this code will never be executed, but unfortunately this compiles
  }

but meant

  if (startPos == cubeOnStart.pos) {
    // this code can be executed if positions are equal
  }

If a method === would be available I would use it by intuition.

Is there a good reason or explanation why such a method is missing?

like image 914
before Avatar asked Nov 02 '13 13:11

before


2 Answers

Equality in Scala is a mess, and the answer to your why question (which Stack Overflow isn't really the ideal venue for) is "because the language designers decided Java interoperability trumped doing the reasonable thing in this case".

At least in recent versions of Scala your startPos == cubeOnStart will result in a warning stating that comparing values of these different types "will always yield false".

The Scalaz library provides the === operator you're looking for via a type-safe Equal type class. You'd write something like this:

import scalaz._, Scalaz._

implicit val cubeEqual = Equal.equalA[Cube]
implicit val posEqual = Equal.equalA[Pos]

Now startPos === cubeOnStart will not compile (which is exactly what we want), but startPos === cubeOnStart.pos will, and will return true.

like image 68
Travis Brown Avatar answered Nov 16 '22 01:11

Travis Brown


As of 2018, there is Multiversal Equality for Dotty. It needs the developers to define the types for which the equality check makes sense, though. All in all, elegant backwards-compatible solution.

like image 35
HappyFace Avatar answered Nov 16 '22 01:11

HappyFace