Add Eq to the standard library

This commit is contained in:
Ayaz Hafiz 2022-10-05 14:33:37 -05:00
parent b2e7fd91ab
commit 16d12a51c2
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
7 changed files with 73 additions and 3 deletions

View file

@ -0,0 +1,39 @@
interface Eq
exposes [
Eq,
isEq,
isNotEq,
]
imports [
Bool,
]
## A type that can be compared for total equality.
##
## Total equality means that all values of the type can be compared to each
## other, and two values `a`, `b` are identical if and only if `isEq a b` is
## `Bool.true`.
##
## Not all types support total equality. For example, an [F32] or [F64] can
## be a `NaN` ([not a number](https://en.wikipedia.org/wiki/NaN)), and the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
## floating point standard specifies that two `NaN`s are never equal to each other.
Eq has
## Returns `Bool.true` if the two values are equal, and `Bool.false` otherwise.
##
## `a == b` is shorthand for `Eq.isEq a b`.
##
## When `isEq` is derived by the Roc compiler, values are compared via
## structural equality. Structural equality works as follows:
##
## 1. Tags are equal if they have the same tag name, and also their contents (if any) are equal.
## 2. Records are equal if all their fields are equal.
## 3. Collections ([Str], [List], [Dict], and [Set]) are equal if they are the same length, and also all their corresponding elements are equal.
## 4. [Num](Num#Num) values are equal if their numbers are equal, with one exception: if both arguments to `isEq` are *NaN*, then `isEq` returns `Bool.false`. See `Num.isNaN` for more about *NaN*.
## 5. Functions can never be compared for structural equality. Roc cannot derive `isEq` for types that contain functions!
isEq : a, a -> Bool | a has Eq
## Calls [isEq] on the given values, then calls [not] on the result.
##
## `a != b` is shorthand for `Eq.isNotEq a b`.
isNotEq : a, a -> Bool | a has Eq
isNotEq = \a, b -> Bool.not (isEq a b)

View file

@ -1291,7 +1291,7 @@ toF64Checked : Num * -> Result F64 [OutOfBounds]*
## >>> Num.isNaN (Num.pow -1 0.5)
##
## *NaN* is unusual from other numberic values in that:
## * *NaN* is not equal to any other number, even itself. [Bool.isEq] always returns `Bool.false` if either argument is *NaN*.
## * *NaN* is not equal to any other number, even itself. [Eq.isEq] always returns `Bool.false` if either argument is *NaN*.
## * *NaN* has no ordering, so [isLt], [isLte], [isGt], and [isGte] always return `Bool.false` if either argument is *NaN*.
##
## These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)