<A>(): Reducer.Reducer<Equivalence<A>>Creates a Reducer for combining Equivalence instances, useful for aggregating equivalences in collections.
When to use
Use when you need a reducer that combines equivalences.
Details
Returns a reducer that combines equivalences using combine. The identity
element for empty collections is an equivalence that always returns true.
The reducer uses combineAll for collections of equivalences and can be used
with fold operations.
Example (Creating a Reducer)
import { Equivalence } from "effect"
const reducer = Equivalence.makeReducer<number>()
const equivalences = [
Equivalence.strictEqual<number>(),
Equivalence.make<number>((a, b) => Math.abs(a - b) < 1)
]
const combined = reducer.combineAll(equivalences)
// Combined equivalence requires both conditions to be true
console.log(combined(1, 1)) // true (strict equal)
console.log(combined(1, 1.5)) // false (strict equal fails)export function function makeReducer<
A
>(): Reducer.Reducer<Equivalence<A>>
Creates a Reducer for combining Equivalence instances, useful for aggregating equivalences in collections.
When to use
Use when you need a reducer that combines equivalences.
Details
Returns a reducer that combines equivalences using combine. The identity
element for empty collections is an equivalence that always returns true.
The reducer uses combineAll for collections of equivalences and can be used
with fold operations.
Example (Creating a Reducer)
import { Equivalence } from "effect"
const reducer = Equivalence.makeReducer<number>()
const equivalences = [
Equivalence.strictEqual<number>(),
Equivalence.make<number>((a, b) => Math.abs(a - b) < 1)
]
const combined = reducer.combineAll(equivalences)
// Combined equivalence requires both conditions to be true
console.log(combined(1, 1)) // true (strict equal)
console.log(combined(1, 1.5)) // false (strict equal fails)
makeReducer<function (type parameter) A in makeReducer<A>(): Reducer.Reducer<Equivalence<A>>A>() {
return import ReducerReducer.function make<A>(
combine: (self: A, that: A) => A,
initialValue: A,
combineAll?: (collection: Iterable<A>) => A
): Reducer<A>
Creates a Reducer from a combine function and an initialValue.
When to use
Use when you have a custom reducing operation not covered by a pre-built reducer.
- You want to provide an optimized
combineAll (e.g. short-circuiting on
a known absorbing element like 0 for multiplication).
Details
- If
combineAll is omitted, a default left-to-right fold starting from
initialValue is used.
- If
combineAll is provided, it completely replaces the default fold.
Example (Multiplying with short-circuit)
import { Reducer } from "effect"
const Product = Reducer.make<number>(
(a, b) => a * b,
1,
(collection) => {
let acc = 1
for (const n of collection) {
if (n === 0) return 0
acc *= n
}
return acc
}
)
console.log(Product.combineAll([2, 3, 4]))
// Output: 24
console.log(Product.combineAll([2, 0, 4]))
// Output: 0
make<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 makeReducer<A>(): Reducer.Reducer<Equivalence<A>>A>>(
const combine: {
<A>(that: Equivalence<A>): (
self: Equivalence<A>
) => Equivalence<A>
<A>(
self: Equivalence<A>,
that: Equivalence<A>
): Equivalence<A>
}
Combines two equivalence relations using logical AND.
When to use
Use when you need to combine exactly two equivalences with AND semantics.
Details
Returns true only if both equivalences return true. The comparison
short-circuits when the first equivalence returns false. The result is also
an equivalence that satisfies reflexive, symmetric, and transitive
properties.
Example (Combining name and age equivalences)
import { Equivalence } from "effect"
interface Person {
name: string
age: number
}
const nameEquivalence = Equivalence.mapInput(
Equivalence.strictEqual<string>(),
(p: Person) => p.name
)
const ageEquivalence = Equivalence.mapInput(
Equivalence.strictEqual<number>(),
(p: Person) => p.age
)
const personEquivalence = Equivalence.combine(nameEquivalence, ageEquivalence)
const person1 = { name: "Alice", age: 30 }
const person2 = { name: "Alice", age: 30 }
const person3 = { name: "Alice", age: 31 }
console.log(personEquivalence(person1, person2)) // true
console.log(personEquivalence(person1, person3)) // false (different age)
combine,
() => true,
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
)
}