Почему метод Scala не имеет типа безопасный эквивалент?

Поскольку изобретатели подчеркивают Scala тип безопасности, я не понимаю отсутствие метода equals на объектах (по крайней мере, из классов case), что позволяет проверять равенство только на объектах одного типа. Я бы хотел, чтобы метод === реализовал это поведение по умолчанию. Разумеется, необходимо, чтобы Java-совместимость имела метод, который работает с типом Any, но во многих случаях я хочу проверить только равенство между объектами того же типа.

Зачем мне это нужно?

Например, у меня есть два класса case и создаю из него объекты

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

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

а затем мне нужно несколько раз проверять позиции и писать случайно

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

но означало

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

Если бы был доступен метод ===, я бы использовал его по интуиции.

Есть ли веская причина или объяснение, почему такой метод отсутствует?

Ответы

Ответ 1

Равенство в Scala является беспорядком, и ответ на ваш вопрос о том, почему этот вопрос (в котором Qaru не является идеальным местом для проведения), "потому что разработчики языка решили, что совместимость с Java сопряжена с разумными соображениями в этом случае".

По крайней мере, в последних версиях Scala ваш startPos == cubeOnStart приведет к предупреждению о том, что сравнение значений этих разных типов всегда будет давать false.

Библиотека Scalaz предоставляет оператор ===, который вы ищете, с помощью типа типа Equal. Вы должны написать что-то вроде этого:

import scalaz._, Scalaz._

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

Теперь startPos === cubeOnStart не будет компилироваться (это именно то, что мы хотим), но startPos === cubeOnStart.pos будет и вернет true.