Number
Number
This module provides utility functions and type class instances for working
with the number type in TypeScript. It includes functions for basic
arithmetic operations, as well as type class instances for Equivalence and
Order.
Operations Reference
| Category | Operation | Description | Domain | Co-domain |
|---|---|---|---|---|
| constructors | :Number.parse | Safely parses a string to a number | string |
Option<number> |
| math | :Number.sum | Adds two numbers | number, number |
number |
| math | :Number.sumAll | Sums all numbers in a collection | Iterable<number> |
number |
| math | :Number.subtract | Subtracts one number from another | number, number |
number |
| math | :Number.multiply | Multiplies two numbers | number, number |
number |
| math | :Number.multiplyAll | Multiplies all numbers in a collection | Iterable<number> |
number |
| math | :Number.divide | Safely divides handling division by zero | number, number |
Option<number> |
| math | :Number.unsafeDivide | Divides but misbehaves for division by zero | number, number |
number |
| math | :Number.remainder | Calculates remainder of division | number, number |
number |
| math | :Number.increment | Adds 1 to a number | number |
number |
| math | :Number.decrement | Subtracts 1 from a number | number |
number |
| math | :Number.sign | Determines the sign of a number | number |
Ordering |
| math | :Number.nextPow2 | Finds the next power of 2 | number |
number |
| math | :Number.round | Rounds a number with specified precision | number, number |
number |
| predicates | :Number.between | Checks if a number is in a range | number, {minimum, maximum} |
boolean |
| predicates | :Number.lessThan | Checks if one number is less than another | number, number |
boolean |
| predicates | :Number.lessThanOrEqualTo | Checks if one number is less than or equal | number, number |
boolean |
| predicates | :Number.greaterThan | Checks if one number is greater than another | number, number |
boolean |
| predicates | :Number.greaterThanOrEqualTo | Checks if one number is greater or equal | number, number |
boolean |
| guards | :Number.isNumber | Type guard for JavaScript numbers | unknown |
boolean |
| comparison | :Number.min | Returns the minimum of two numbers | number, number |
number |
| comparison | :Number.max | Returns the maximum of two numbers | number, number |
number |
| comparison | :Number.clamp | Restricts a number to a range | number, {minimum, maximum} |
number |
| instances | :Number.Equivalence | Equivalence instance for numbers | Equivalence<number> |
|
| instances | :Number.Order | Order instance for numbers | Order<number> |
|
| errors | :Number.DivisionByZeroError | Error thrown by unsafeDivide |
Composition Patterns and Type Safety
When building function pipelines, understanding how types flow through operations is critical:
Composing with type-preserving operations
Most operations in this module are type-preserving (number → number),
making them easily composable in pipelines:
Working with Option results
Operations that might fail (like division by zero) return Option types and require Option combinators:
Composition best practices
- Chain type-preserving operations for maximum composability
- Use Option combinators when working with potentially failing operations
- Consider using Effect for operations that might fail with specific errors
- Remember that all operations maintain JavaScript's floating-point precision limitations
See
- :BigInt for more similar operations on
biginttypes - :BigDecimal for more similar operations on
BigDecimaltypes
Example
import { pipe } from "effect"import * as Number from "effect/Number"
const result = pipe( 10, Number.increment, // number → number Number.multiply(2), // number → number Number.round(1) // number → number) // Result: number (21)Example
import { pipe, Option } from "effect"import * as Number from "effect/Number"
const result = pipe( 10, Number.divide(0), // number → Option<number> Option.getOrElse(() => 0) // Option<number> → number) // Result: number (0)Constructors
Guards
Type guard that tests if a value is a member of the set of JavaScript numbers.
Signature
declare const isNumber: (input: unknown) => input is numberExample
import * as assert from "node:assert/strict"import * as Number from "effect/Number"
// Regular numbersassert.equal(Number.isNumber(2), true)assert.equal(Number.isNumber(-3.14), true)assert.equal(Number.isNumber(0), true)
// Special numeric valuesassert.equal(Number.isNumber(Infinity), true)assert.equal(Number.isNumber(NaN), true)
// Non-number valuesassert.equal(Number.isNumber("2"), false)assert.equal(Number.isNumber(true), false)assert.equal(Number.isNumber(null), false)assert.equal(Number.isNumber(undefined), false)assert.equal(Number.isNumber({}), false)assert.equal(Number.isNumber([]), false)
// Using as a type guard in conditionalsfunction processValue(value: unknown): string { if (Number.isNumber(value)) { // TypeScript now knows 'value' is a number return `Numeric value: ${value.toFixed(2)}` } return "Not a number"}
assert.strictEqual(processValue(42), "Numeric value: 42.00")assert.strictEqual(processValue("hello"), "Not a number")
// Filtering for numbers in an arrayconst mixed = [1, "two", 3, false, 5]const onlyNumbers = mixed.filter(Number.isNumber)assert.equal(onlyNumbers, [1, 3, 5])Instances
Equivalence
Signature
declare const Equivalence: equivalence.Equivalence<number>Signature
declare const Order: order.Order<number>Math
Decrements a number by 1.
Signature
declare function decrement(n: number): numberExample
import * as assert from "node:assert/strict"import { decrement } from "effect/Number"
assert.equal(decrement(3), 2)Performs division in the set of JavaScript numbers, returning the result
wrapped in an Option to handle division by zero.
Signature
declare const divide: { (divisor: number): (dividend: number) => Option<number>; (dividend: number, divisor: number): Option<number>;}Example
import * as assert from "node:assert/strict"import { pipe, Option } from "effect"import * as Number from "effect/Number"
// Data-first style (direct application)assert.equal(Number.divide(6, 3), Option.some(2)) // 6 ÷ 3 = 2assert.equal(Number.divide(-8, 4), Option.some(-2)) // (-8) ÷ 4 = -2assert.equal(Number.divide(-10, -5), Option.some(2)) // (-10) ÷ (-5) = 2assert.equal(Number.divide(1, 3), Option.some(0.3333333333333333)) // Note: floating-point approximation
// Handling division by zeroassert.equal(Number.divide(6, 0), Option.none()) // 6 ÷ 0 is undefined
// Data-last style (pipeable)assert.equal( pipe( 10, Number.divide(2) // 10 ÷ 2 = 5 ), Option.some(5))
// Chaining multiple divisions using Option combinatorsassert.equal( pipe( Option.some(24), Option.flatMap((n) => Number.divide(n, 2)), // 24 ÷ 2 = 12 Option.flatMap(Number.divide(3)), // 12 ÷ 3 = 4 Option.flatMap(Number.divide(2)) // 4 ÷ 2 = 2 ), Option.some(2))
// Division-by-one property: a ÷ 1 = aassert.equal(Number.divide(42, 1), Option.some(42))
// Self-division property: a ÷ a = 1 (for a ≠ 0)assert.equal(Number.divide(42, 42), Option.some(1))
// Non-commutative property: a ÷ b ≠ b ÷ aassert.notDeepStrictEqual( Number.divide(6, 3), // 6 ÷ 3 = 2 Number.divide(3, 6) // 3 ÷ 6 = 0.5)Returns the result of adding 1 to a given number.
Signature
declare function increment(n: number): numberExample
import * as assert from "node:assert/strict"import { increment } from "effect/Number"
assert.equal(increment(2), 3)Performs multiplication in the set of JavaScript numbers.
Signature
declare const multiply: { (multiplicand: number): (multiplier: number) => number; (multiplier: number, multiplicand: number): number;}Example
import * as assert from "node:assert/strict"import { pipe } from "effect"import * as Number from "effect/Number"
// Data-first style (direct application)assert.equal(Number.multiply(2, 3), 6) // 2 × 3 = 6assert.equal(Number.multiply(-4, 5), -20) // (-4) × 5 = -20assert.equal(Number.multiply(-3, -2), 6) // (-3) × (-2) = 6assert.equal(Number.multiply(0.1, 0.2), 0.020000000000000004) // Note: floating-point precision limitation
// Data-last style (pipeable)assert.equal( pipe( 10, Number.multiply(5) // 10 × 5 = 50 ), 50)
// Chaining multiple multiplicationsassert.equal( pipe( 2, Number.multiply(3), // 2 × 3 = 6 Number.multiply(4), // 6 × 4 = 24 Number.multiply(0.5) // 24 × 0.5 = 12 ), 12)
// Identity property: a × 1 = aassert.equal(Number.multiply(42, 1), 42)
// Zero property: a × 0 = 0assert.equal(Number.multiply(42, 0), 0)
// Commutative property: a × b = b × aassert.equal(Number.multiply(5, 3), Number.multiply(3, 5))
// Associative property: (a × b) × c = a × (b × c)const a = 2, b = 3, c = 4assert.equal( Number.multiply(Number.multiply(a, b), c), Number.multiply(a, Number.multiply(b, c)))multiplyAll
Computes the product of all elements in an iterable collection of numbers.
Signature
declare function multiplyAll(collection: Iterable<number>): numberExample
import * as assert from "node:assert/strict"import * as Number from "effect/Number"
// Basic productsassert.equal(Number.multiplyAll([2, 3, 4]), 24) // 2 × 3 × 4 = 24assert.equal(Number.multiplyAll([1.5, 2, 3]), 9) // 1.5 × 2 × 3 = 9
// Empty collection returns the multiplicative identity (1)assert.equal(Number.multiplyAll([]), 1)
// Single element collectionassert.equal(Number.multiplyAll([42]), 42)
// Products with negative numbersassert.equal(Number.multiplyAll([2, -3, 4]), -24) // 2 × (-3) × 4 = -24assert.equal(Number.multiplyAll([-2, -3]), 6) // (-2) × (-3) = 6
// Zero property - if any element is zero, product is zeroassert.equal(Number.multiplyAll([2, 0, 3]), 0)
// Works with any iterableassert.equal(Number.multiplyAll(new Set([2, 3, 4])), 24)
// Using with generated sequencesfunction* range(start: number, end: number) { for (let i = start; i <= end; i++) yield i}
// Compute factorial: 5! = 5 × 4 × 3 × 2 × 1 = 120assert.equal(Number.multiplyAll(range(1, 5)), 120)Returns the next power of 2 greater than or equal to the given number.
- For
positiveinputs, returns the smallest power of 2 that is >= the input - For
zero, returns 2 - For
negativeinputs, returns NaN (as logarithms of negative numbers are undefined) - For
NaNinput, returns NaN - For
Infinity, returns Infinity
Signature
declare function nextPow2(n: number): numberExample
import * as assert from "node:assert/strict"import { nextPow2 } from "effect/Number"
assert.equal(nextPow2(5), 8)assert.equal(nextPow2(17), 32)assert.equal(nextPow2(0), 2)assert.equal(Number.isNaN(nextPow2(-1)), true) // Negative inputs result in NaNReturns the remainder left over when one operand is divided by a second operand.
It always takes the sign of the dividend.
Signature
declare const remainder: { (divisor: number): (dividend: number) => number; (dividend: number, divisor: number): number;}Example
import * as assert from "node:assert/strict"import { remainder } from "effect/Number"
assert.equal(remainder(2, 2), 0)assert.equal(remainder(3, 2), 1)assert.equal(remainder(-4, 2), -0)Returns the number rounded with the given precision.
Signature
declare const round: { (precision: number): (self: number) => number; (self: number, precision: number): number;}Example
import * as assert from "node:assert/strict"import { round } from "effect/Number"
assert.equal(round(1.1234, 2), 1.12)assert.equal(round(1.567, 2), 1.57)Determines the sign of a given number.
Signature
declare function sign(n: number): OrderingExample
import * as assert from "node:assert/strict"import { sign } from "effect/Number"
assert.equal(sign(-5), -1)assert.equal(sign(0), 0)assert.equal(sign(5), 1)Performs subtraction in the set of JavaScript numbers.
Signature
declare const subtract: { (subtrahend: number): (minuend: number) => number; (minuend: number, subtrahend: number): number;}Example
import * as assert from "node:assert/strict"import { pipe } from "effect"import * as Number from "effect/Number"
// Data-first style (direct application)assert.equal(Number.subtract(2, 3), -1) // 2 - 3 = -1assert.equal(Number.subtract(10, 5), 5) // 10 - 5 = 5assert.equal(Number.subtract(0.3, 0.1), 0.19999999999999998) // Note: floating-point precision limitation
// Data-last style (pipeable)assert.equal( pipe( 10, Number.subtract(5) // 10 - 5 = 5 ), 5)
// Chaining multiple subtractionsassert.equal( pipe( 20, Number.subtract(5), // 20 - 5 = 15 Number.subtract(3), // 15 - 3 = 12 Number.subtract(2) // 12 - 2 = 10 ), 10)
// Right identity property: a - 0 = aassert.equal(Number.subtract(42, 0), 42)
// Self-annihilation property: a - a = 0assert.equal(Number.subtract(42, 42), 0)
// Non-commutative property: a - b ≠ b - aassert.equal(Number.subtract(5, 3), 2) // 5 - 3 = 2assert.equal(Number.subtract(3, 5), -2) // 3 - 5 = -2
// Inverse relation: a - b = -(b - a)assert.equal(Number.subtract(5, 3), -Number.subtract(3, 5))Performs addition in the set of JavaScript numbers.
Signature
declare const sum: { (that: number): (self: number) => number; (self: number, that: number): number;}Example
import * as assert from "node:assert/strict"import { pipe } from "effect"import * as Number from "effect/Number"
// Data-first style (direct application)assert.equal(Number.sum(2, 3), 5)assert.equal(Number.sum(-10, 5), -5)assert.equal(Number.sum(0.1, 0.2), 0.30000000000000004) // Note: floating-point precision limitation
// Data-last style (pipeable)assert.equal( pipe( 10, Number.sum(5) // 10 + 5 = 15 ), 15)
// Chaining multiple additionsassert.equal( pipe( 1, Number.sum(2), // 1 + 2 = 3 Number.sum(3), // 3 + 3 = 6 Number.sum(4) // 6 + 4 = 10 ), 10)
// Identity property: a + 0 = aassert.equal(Number.sum(42, 0), 42)
// Commutative property: a + b = b + aassert.equal(Number.sum(5, 3), Number.sum(3, 5))Computes the sum of all elements in an iterable collection of numbers.
Signature
declare function sumAll(collection: Iterable<number>): numberExample
import * as assert from "node:assert/strict"import * as Number from "effect/Number"
// Basic sumsassert.equal(Number.sumAll([2, 3, 4]), 9) // 2 + 3 + 4 = 9assert.equal(Number.sumAll([1.1, 2.2, 3.3]), 6.6) // 1.1 + 2.2 + 3.3 = 6.6
// Empty collection returns the additive identity (0)assert.equal(Number.sumAll([]), 0)
// Single element collectionassert.equal(Number.sumAll([42]), 42)
// Sums with negative numbersassert.equal(Number.sumAll([2, -3, 4]), 3) // 2 + (-3) + 4 = 3assert.equal(Number.sumAll([-2, -3, -4]), -9) // (-2) + (-3) + (-4) = -9
// Works with any iterableassert.equal(Number.sumAll(new Set([2, 3, 4])), 9)
// Using with generated sequencesfunction* range(start: number, end: number) { for (let i = start; i <= end; i++) yield i}
// Compute sum of first 5 natural numbers: 1 + 2 + 3 + 4 + 5 = 15assert.equal(Number.sumAll(range(1, 5)), 15)
// Floating point precision exampleassert.equal( Number.sumAll([0.1, 0.2]), 0.30000000000000004 // Note IEEE 754 precision limitation)unsafeDivide
Performs division in the set of JavaScript numbers, but misbehaves for division by zero.
Unlike :Number.divide which returns an Option, this function
directly returns a number or Infinity or NaN.
- If the
divisoris zero, it returnsInfinity. - If both the
dividendand thedivisorare zero, then it returnsNaN.
See
- :Number.divide - Safe division returning an Option
Signature
declare const unsafeDivide: { (divisor: number): (dividend: number) => number; (dividend: number, divisor: number): number;}Example
import * as assert from "node:assert/strict"import { pipe } from "effect"import * as Number from "effect/Number"
// Data-first style (direct application)assert.equal(Number.unsafeDivide(6, 3), 2) // 6 ÷ 3 = 2assert.equal(Number.unsafeDivide(-8, 4), -2) // (-8) ÷ 4 = -2assert.equal(Number.unsafeDivide(-10, -5), 2) // (-10) ÷ (-5) = 2assert.equal(Number.unsafeDivide(1, 3), 0.3333333333333333)
// Data-last style (pipeable)assert.equal( pipe( 10, Number.unsafeDivide(2) // 10 ÷ 2 = 5 ), 5)
// Chaining multiple divisionsassert.equal( pipe( 24, Number.unsafeDivide(2), // 24 ÷ 2 = 12 Number.unsafeDivide(3), // 12 ÷ 3 = 4 Number.unsafeDivide(2) // 4 ÷ 2 = 2 ), 2)
assert.equal(Number.unsafeDivide(6, 0), Infinity)
assert.equal(Number.unsafeDivide(0, 0), NaN)
// Compare with safe divisionconst safeResult = Number.divide(6, 3) // Option.some(2)const unsafeResult = Number.unsafeDivide(6, 3) // 2 directlyOther
Restricts the given number to be within the range specified by the
minimum and maximum values.
- If the
numberis less than theminimumvalue, the function returns theminimumvalue. - If the
numberis greater than themaximumvalue, the function returns themaximumvalue. - Otherwise, it returns the original
number.
Signature
declare const clamp: { (options: { maximum: number; minimum: number; }): (self: number) => number; (self: number, options: { maximum: number; minimum: number; }): number;}Example
import * as assert from "node:assert/strict"import { Number } from "effect"
const clamp = Number.clamp({ minimum: 1, maximum: 5 })
assert.equal(clamp(3), 3)assert.equal(clamp(0), 1)assert.equal(clamp(6), 5)Returns the maximum between two numbers.
Signature
declare const max: { (that: number): (self: number) => number; (self: number, that: number): number;}Example
import * as assert from "node:assert/strict"import { max } from "effect/Number"
assert.equal(max(2, 3), 3)Returns the minimum between two numbers.
Signature
declare const min: { (that: number): (self: number) => number; (self: number, that: number): number;}Example
import * as assert from "node:assert/strict"import { min } from "effect/Number"
assert.equal(min(2, 3), 2)Returns the additive inverse of a number, effectively negating it.
Signature
declare function negate(n: number): numberExample
import * as assert from "node:assert/strict"import { pipe } from "effect"import * as Number from "effect/Number"
assert.equal( Number.negate(5), // -5)
assert.equal( Number.negate(-5), // 5)
assert.equal( Number.negate(0), // 0)Predicates
Checks if a number is between a minimum and maximum value (inclusive).
Signature
declare const between: { (options: { maximum: number; minimum: number; }): (self: number) => boolean; (self: number, options: { maximum: number; minimum: number; }): boolean;}Example
import * as assert from "node:assert/strict"import { Number } from "effect"
const between = Number.between({ minimum: 0, maximum: 5 })
assert.equal(between(3), true)assert.equal(between(-1), false)assert.equal(between(6), false)greaterThan
Returns true if the first argument is greater than the second, otherwise
false.
Signature
declare const greaterThan: { (that: number): (self: number) => boolean; (self: number, that: number): boolean;}Example
import * as assert from "node:assert/strict"import { greaterThan } from "effect/Number"
assert.equal(greaterThan(2, 3), false)assert.equal(greaterThan(3, 3), false)assert.equal(greaterThan(4, 3), true)greaterThanOrEqualTo
Returns a function that checks if a given number is greater than or equal
to the provided one.
Signature
declare const greaterThanOrEqualTo: { (that: number): (self: number) => boolean; (self: number, that: number): boolean;}Example
import * as assert from "node:assert/strict"import { greaterThanOrEqualTo } from "effect/Number"
assert.equal(greaterThanOrEqualTo(2, 3), false)assert.equal(greaterThanOrEqualTo(3, 3), true)assert.equal(greaterThanOrEqualTo(4, 3), true)Returns true if the first argument is less than the second, otherwise
false.
Signature
declare const lessThan: { (that: number): (self: number) => boolean; (self: number, that: number): boolean;}Example
import * as assert from "node:assert/strict"import { lessThan } from "effect/Number"
assert.equal(lessThan(2, 3), true)assert.equal(lessThan(3, 3), false)assert.equal(lessThan(4, 3), false)lessThanOrEqualTo
Returns a function that checks if a given number is less than or equal to
the provided one.
Signature
declare const lessThanOrEqualTo: { (that: number): (self: number) => boolean; (self: number, that: number): boolean;}Example
import * as assert from "node:assert/strict"import { lessThanOrEqualTo } from "effect/Number"
assert.equal(lessThanOrEqualTo(2, 3), true)assert.equal(lessThanOrEqualTo(3, 3), true)assert.equal(lessThanOrEqualTo(4, 3), false)