Skip to content

Equivalence

The Equivalence module provides a way to define equivalence relations between values in TypeScript. An equivalence relation is a binary relation that is reflexive, symmetric, and transitive, establishing a formal notion of when two values should be considered equivalent.

An Equivalence<A> represents a function that compares two values of type A and determines if they are equivalent. This is more flexible and customizable than simple equality checks using ===.

Here’s the structure of an Equivalence:

interface Equivalence<A> {
(self: A, that: A): boolean
}

The module provides several built-in equivalence relations for common data types:

EquivalenceDescription
stringUses strict equality (===) for strings
numberUses strict equality (===) for numbers
booleanUses strict equality (===) for booleans
symbolUses strict equality (===) for symbols
bigintUses strict equality (===) for bigints
DateCompares Date objects by their timestamps

Example (Using Built-in Equivalences)

import {
import Equivalence
Equivalence
} from "effect"
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Equivalence
Equivalence
.
const string: Equivalence.Equivalence
(self: string, that: string) => boolean

@since2.0.0

string
("apple", "apple"))
// Output: true
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Equivalence
Equivalence
.
const string: Equivalence.Equivalence
(self: string, that: string) => boolean

@since2.0.0

string
("apple", "orange"))
// Output: false
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Equivalence
Equivalence
.
const Date: Equivalence.Equivalence
(self: Date, that: Date) => boolean

@since2.0.0

Date
(new
var Date: DateConstructor
new (year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number) => Date (+3 overloads)

Creates a new Date.

@paramyear The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.

@parammonthIndex The month as a number between 0 and 11 (January to December).

@paramdate The date as a number between 1 and 31.

@paramhours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.

@paramminutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.

@paramseconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.

@paramms A number from 0 to 999 that specifies the milliseconds.

Date
(2023, 1, 1), new
var Date: DateConstructor
new (year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number) => Date (+3 overloads)

Creates a new Date.

@paramyear The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.

@parammonthIndex The month as a number between 0 and 11 (January to December).

@paramdate The date as a number between 1 and 31.

@paramhours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.

@paramminutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.

@paramseconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.

@paramms A number from 0 to 999 that specifies the milliseconds.

Date
(2023, 1, 1)))
// Output: true
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
import Equivalence
Equivalence
.
const Date: Equivalence.Equivalence
(self: Date, that: Date) => boolean

@since2.0.0

Date
(new
var Date: DateConstructor
new (year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number) => Date (+3 overloads)

Creates a new Date.

@paramyear The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.

@parammonthIndex The month as a number between 0 and 11 (January to December).

@paramdate The date as a number between 1 and 31.

@paramhours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.

@paramminutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.

@paramseconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.

@paramms A number from 0 to 999 that specifies the milliseconds.

Date
(2023, 1, 1), new
var Date: DateConstructor
new (year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number) => Date (+3 overloads)

Creates a new Date.

@paramyear The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.

@parammonthIndex The month as a number between 0 and 11 (January to December).

@paramdate The date as a number between 1 and 31.

@paramhours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.

@paramminutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.

@paramseconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.

@paramms A number from 0 to 999 that specifies the milliseconds.

Date
(2023, 10, 1)))
// Output: false

For more complex data structures, you may need custom equivalences. The Equivalence module lets you derive new Equivalence instances from existing ones with the Equivalence.mapInput function.

Example (Creating a Custom Equivalence for Objects)

import {
import Equivalence
Equivalence
} from "effect"
interface
interface User
User
{
readonly
User.id: number
id
: number
readonly
User.name: string
name
: string
}
// Create an equivalence that compares User objects based only on the id
const
const equivalence: Equivalence.Equivalence<User>
equivalence
=
import Equivalence
Equivalence
.
const mapInput: <number, User>(self: Equivalence.Equivalence<number>, f: (b: User) => number) => Equivalence.Equivalence<User> (+1 overload)

@since2.0.0

mapInput
(
import Equivalence
Equivalence
.
const number: Equivalence.Equivalence<number>

@since2.0.0

number
, // Base equivalence for comparing numbers
(
user: User
user
:
interface User
User
) =>
user: User
user
.
User.id: number
id
// Function to extract the id from a User
)
// Compare two User objects: they are equivalent if their ids are the same
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const equivalence: Equivalence.Equivalence
(self: User, that: User) => boolean
equivalence
({
User.id: number
id
: 1,
User.name: string
name
: "Alice" }, {
User.id: number
id
: 1,
User.name: string
name
: "Al" }))
// Output: true

The Equivalence.mapInput function takes two arguments:

  1. The existing Equivalence you want to use as a base (Equivalence.number in this case, for comparing numbers).
  2. A function that extracts the value used for the equivalence check from your data structure ((user: User) => user.id in this case).