<A>(collection: Iterable<Equivalence<A>>): Equivalence<A>Combines multiple equivalence relations into a single equivalence using logical AND.
When to use
Use when you need to combine many Equivalence instances from an iterable.
Details
Returns true only if all equivalences in the collection return true. The
comparison stops at the first equivalence that returns false. Empty
collections return an equivalence that always returns true. The result is
also an equivalence that satisfies reflexive, symmetric, and transitive
properties.
Example (Combining multiple field equivalences)
import { Equivalence } from "effect"
interface Point3D {
x: number
y: number
z: number
}
const xEq = Equivalence.mapInput(
Equivalence.strictEqual<number>(),
(p: Point3D) => p.x
)
const yEq = Equivalence.mapInput(
Equivalence.strictEqual<number>(),
(p: Point3D) => p.y
)
const zEq = Equivalence.mapInput(
Equivalence.strictEqual<number>(),
(p: Point3D) => p.z
)
const point3DEq = Equivalence.combineAll([xEq, yEq, zEq])
const point1 = { x: 1, y: 2, z: 3 }
const point2 = { x: 1, y: 2, z: 3 }
const point3 = { x: 1, y: 2, z: 4 }
console.log(point3DEq(point1, point2)) // true
console.log(point3DEq(point1, point3)) // false (different z)Example (Handling empty collections)
import { Equivalence } from "effect"
// Empty collection always returns true
const alwaysEq = Equivalence.combineAll([])
console.log(alwaysEq("anything", "else")) // trueexport const const combineAll: <A>(
collection: Iterable<Equivalence<A>>
) => Equivalence<A>
Combines multiple equivalence relations into a single equivalence using logical AND.
When to use
Use when you need to combine many Equivalence instances from an iterable.
Details
Returns true only if all equivalences in the collection return true. The
comparison stops at the first equivalence that returns false. Empty
collections return an equivalence that always returns true. The result is
also an equivalence that satisfies reflexive, symmetric, and transitive
properties.
Example (Combining multiple field equivalences)
import { Equivalence } from "effect"
interface Point3D {
x: number
y: number
z: number
}
const xEq = Equivalence.mapInput(
Equivalence.strictEqual<number>(),
(p: Point3D) => p.x
)
const yEq = Equivalence.mapInput(
Equivalence.strictEqual<number>(),
(p: Point3D) => p.y
)
const zEq = Equivalence.mapInput(
Equivalence.strictEqual<number>(),
(p: Point3D) => p.z
)
const point3DEq = Equivalence.combineAll([xEq, yEq, zEq])
const point1 = { x: 1, y: 2, z: 3 }
const point2 = { x: 1, y: 2, z: 3 }
const point3 = { x: 1, y: 2, z: 4 }
console.log(point3DEq(point1, point2)) // true
console.log(point3DEq(point1, point3)) // false (different z)
Example (Handling empty collections)
import { Equivalence } from "effect"
// Empty collection always returns true
const alwaysEq = Equivalence.combineAll([])
console.log(alwaysEq("anything", "else")) // true
combineAll = <function (type parameter) A in <A>(collection: Iterable<Equivalence<A>>): Equivalence<A>A>(collection: Iterable<Equivalence<A>>collection: interface Iterable<T, TReturn = any, TNext = any>Iterable<type Equivalence<in A> = (
self: A,
that: A
) => boolean
Represents an equivalence relation over type A.
When to use
Use as a type annotation when you accept or return an equivalence function.
Details
- Returns
boolean: true if values are equivalent, false otherwise
- Must satisfy reflexive, symmetric, and transitive properties
Example (Defining simple number equivalence)
import type { Equivalence } from "effect"
const numberEq: Equivalence.Equivalence<number> = (a, b) => a === b
console.log(numberEq(1, 1)) // true
console.log(numberEq(1, 2)) // false
Example (Defining custom object equivalence)
import type { Equivalence } from "effect"
interface Point {
x: number
y: number
}
const pointEq: Equivalence.Equivalence<Point> = (a, b) =>
a.x === b.x && a.y === b.y
console.log(pointEq({ x: 1, y: 2 }, { x: 1, y: 2 })) // true
Equivalence<function (type parameter) A in <A>(collection: Iterable<Equivalence<A>>): Equivalence<A>A>>): type Equivalence<in A> = (
self: A,
that: A
) => boolean
Represents an equivalence relation over type A.
When to use
Use as a type annotation when you accept or return an equivalence function.
Details
- Returns
boolean: true if values are equivalent, false otherwise
- Must satisfy reflexive, symmetric, and transitive properties
Example (Defining simple number equivalence)
import type { Equivalence } from "effect"
const numberEq: Equivalence.Equivalence<number> = (a, b) => a === b
console.log(numberEq(1, 1)) // true
console.log(numberEq(1, 2)) // false
Example (Defining custom object equivalence)
import type { Equivalence } from "effect"
interface Point {
x: number
y: number
}
const pointEq: Equivalence.Equivalence<Point> = (a, b) =>
a.x === b.x && a.y === b.y
console.log(pointEq({ x: 1, y: 2 }, { x: 1, y: 2 })) // true
Equivalence<function (type parameter) A in <A>(collection: Iterable<Equivalence<A>>): Equivalence<A>A> =>
const make: <A>(
isEquivalent: (self: A, that: A) => boolean
) => Equivalence<A>
Creates a custom equivalence relation with an optimized reference equality check.
When to use
Use when you need an equality rule that the built-in instances and input
mapping helpers cannot express, and you can provide a law-abiding comparison.
Details
The returned equivalence first checks reference equality (===) for
performance. If the values are not the same reference, it falls back to the
provided equivalence function, which must satisfy reflexive, symmetric, and
transitive properties.
Example (Case-insensitive string equivalence)
import { Equivalence } from "effect"
const caseInsensitive = Equivalence.make<string>((a, b) =>
a.toLowerCase() === b.toLowerCase()
)
console.log(caseInsensitive("Hello", "HELLO")) // true
console.log(caseInsensitive("foo", "bar")) // false
// Same reference optimization
const str = "test"
console.log(caseInsensitive(str, str)) // true (fast path)
Example (Comparing numbers with tolerance)
import { Equivalence } from "effect"
const tolerance = Equivalence.make<number>((a, b) => Math.abs(a - b) < 0.0001)
console.log(tolerance(1.0, 1.001)) // false
console.log(tolerance(1.0, 1.00001)) // true
make((x: Ax, y: Ay) => {
for (const const equivalence: Equivalence<A>equivalence of collection: Iterable<Equivalence<A>>collection) {
if (!const equivalence: Equivalence<A>equivalence(x: Ax, y: Ay)) {
return false
}
}
return true
})