scalabook

Форк
0
92 строки · 3.4 Кб

Equal

Формальное определение

Класс типов Equal

описывает тип, который можно сравнивать на наблюдаемое равенство.

Equal

должен следовать следующим законам:

  • Рефлексивность: x == x
    для любого x
  • Неразличимость тождеств (антисимметрия): для любых x
    и y
    , если x == y
    , то x
    и y
    неразличимы.
  • Личность неразличимых: для любых x
    и y
    , если x
    и y
    неразличимы, то x == y

Неразличимость формализует интуитивное представление о двух объектах, обладающих точно такими же свойствами. Два значения x, y: A

неразличимы, если не существует такой функции f: A => Boolean
, что f(x)
- true
, а f(y)
- false
.

Эти законы влекут за собой симметрию и транзитивность, которые должно быть легче проверить, поскольку они не дают универсальной количественной оценки для всех возможных предикатов в языке:

  • Симметричность: x == y
    тогда и только тогда, когда y == x
  • Транзитивность: если x == y
    и y == z
    , тогда x == z

Если есть преобразование f: G => F

, то из Equal[F]
можно получить Equal[G]
.

Определение в виде кода на Scala

trait Equal[F]:
self =>
def equal(a1: F, a2: F): Boolean
def notEqual(a1: F, a2: F): Boolean = !equal(a1, a2)
def contramap[G](f: G => F): Equal[G] =
(a1: G, a2: G) => self.equal(f(a1), f(a2))

Реализация

Реализация в Cats

import cats.*
import cats.implicits.*
1 === 1 // true
"Hello" =!= "World" // true
123 === "123" // Не скомпилируется: Type Mismatch Error
1.some =!= none[Int] // true
final case class Cat(name: String, age: Int, color: String)
given Eq[Cat] =
Eq.instance[Cat] { (cat1, cat2) =>
(cat1.name === cat2.name ) &&
(cat1.age === cat2.age ) &&
(cat1.color === cat2.color)
}
val cat1 = Cat("Garfield", 38, "orange and black")
val cat2 = Cat("Heathcliff", 32, "orange and black")
cat1 === cat2 // false

Реализация в ScalaZ

import scalaz.*
import Scalaz.*
List(1, 2, 3) === List(1, 2, 3) // true
List(1, 2, 3) =/= List(1, 2, 4) // true

Реализация в Spire

import spire.math.Rational
import spire.syntax.all.*
Rational(2, 4) === Rational(3, 6) // true
Rational(2, 6) =!= Rational(3, 6) // true

Ссылки:

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.