Number.ts overview
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 | module:Number.parse | Safely parses a string to a number | string | Option<number> |
math | module:Number.sum | Adds two numbers | number , number | number |
math | module:Number.sumAll | Sums all numbers in a collection | Iterable<number> | number |
math | module:Number.subtract | Subtracts one number from another | number , number | number |
math | module:Number.multiply | Multiplies two numbers | number , number | number |
math | module:Number.multiplyAll | Multiplies all numbers in a collection | Iterable<number> | number |
math | module:Number.divide | Safely divides handling division by zero | number , number | Option<number> |
math | module:Number.unsafeDivide | Divides but misbehaves for division by zero | number , number | number |
math | module:Number.remainder | Calculates remainder of division | number , number | number |
math | module:Number.increment | Adds 1 to a number | number | number |
math | module:Number.decrement | Subtracts 1 from a number | number | number |
math | module:Number.sign | Determines the sign of a number | number | Ordering |
math | module:Number.nextPow2 | Finds the next power of 2 | number | number |
math | module:Number.round | Rounds a number with specified precision | number , number | number |
predicates | module:Number.between | Checks if a number is in a range | number , {minimum, maximum} | boolean |
predicates | module:Number.lessThan | Checks if one number is less than another | number , number | boolean |
predicates | module:Number.lessThanOrEqualTo | Checks if one number is less than or equal | number , number | boolean |
predicates | module:Number.greaterThan | Checks if one number is greater than another | number , number | boolean |
predicates | module:Number.greaterThanOrEqualTo | Checks if one number is greater or equal | number , number | boolean |
guards | module:Number.isNumber | Type guard for JavaScript numbers | unknown | boolean |
comparison | module:Number.min | Returns the minimum of two numbers | number , number | number |
comparison | module:Number.max | Returns the maximum of two numbers | number , number | number |
comparison | module:Number.clamp | Restricts a number to a range | number , {minimum, maximum} | number |
instances | module:Number.Equivalence | Equivalence instance for numbers | Equivalence<number> | |
instances | module:Number.Order | Order instance for numbers | Order<number> | |
errors | module: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:
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)
Working with Option results
Operations that might fail (like division by zero) return Option types and require Option combinators:
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)
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
module:BigInt
for more similar operations onbigint
typesmodule:BigDecimal
for more similar operations onBigDecimal
types
Since v2.0.0
Exports Grouped by Category
constructors
parse
Tries to parse a number
from a string
using the Number()
function. The following special string values are supported: “NaN”, “Infinity”, “-Infinity”.
Signature
declare const parse: (s: string) => Option<number>
Since v2.0.0
guards
isNumber
Type guard that tests if a value is a member of the set of JavaScript numbers.
Example
import * as assert from "node:assert/strict"
import * as Number from "effect/Number"
// Regular numbers
assert.equal(Number.isNumber(2), true)
assert.equal(Number.isNumber(-3.14), true)
assert.equal(Number.isNumber(0), true)
// Special numeric values
assert.equal(Number.isNumber(Infinity), true)
assert.equal(Number.isNumber(NaN), true)
// Non-number values
assert.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 conditionals
function 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 array
const mixed = [1, "two", 3, false, 5]
const onlyNumbers = mixed.filter(Number.isNumber)
assert.equal(onlyNumbers, [1, 3, 5])
Signature
declare const isNumber: (input: unknown) => input is number
Since v2.0.0
instances
Equivalence
Signature
declare const Equivalence: equivalence.Equivalence<number>
Since v2.0.0
Order
Signature
declare const Order: order.Order<number>
Since v2.0.0
math
decrement
Decrements a number by 1
.
Example
import * as assert from "node:assert/strict"
import { decrement } from "effect/Number"
assert.equal(decrement(3), 2)
Signature
declare const decrement: (n: number) => number
Since v2.0.0
divide
Performs division in the set of JavaScript numbers, returning the result wrapped in an Option
to handle division by zero.
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 = 2
assert.equal(Number.divide(-8, 4), Option.some(-2)) // (-8) ÷ 4 = -2
assert.equal(Number.divide(-10, -5), Option.some(2)) // (-10) ÷ (-5) = 2
assert.equal(Number.divide(1, 3), Option.some(0.3333333333333333)) // Note: floating-point approximation
// Handling division by zero
assert.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 combinators
assert.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 = a
assert.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 ÷ a
assert.notDeepStrictEqual(
Number.divide(6, 3), // 6 ÷ 3 = 2
Number.divide(3, 6) // 3 ÷ 6 = 0.5
)
Signature
declare const divide: {
(divisor: number): (dividend: number) => Option<number>
(dividend: number, divisor: number): Option<number>
}
Since v2.0.0
increment
Returns the result of adding 1
to a given number.
Example
import * as assert from "node:assert/strict"
import { increment } from "effect/Number"
assert.equal(increment(2), 3)
Signature
declare const increment: (n: number) => number
Since v2.0.0
multiply
Performs multiplication in the set of JavaScript numbers.
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 = 6
assert.equal(Number.multiply(-4, 5), -20) // (-4) × 5 = -20
assert.equal(Number.multiply(-3, -2), 6) // (-3) × (-2) = 6
assert.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 multiplications
assert.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 = a
assert.equal(Number.multiply(42, 1), 42)
// Zero property: a × 0 = 0
assert.equal(Number.multiply(42, 0), 0)
// Commutative property: a × b = b × a
assert.equal(Number.multiply(5, 3), Number.multiply(3, 5))
// Associative property: (a × b) × c = a × (b × c)
const a = 2,
b = 3,
c = 4
assert.equal(Number.multiply(Number.multiply(a, b), c), Number.multiply(a, Number.multiply(b, c)))
Signature
declare const multiply: {
(multiplicand: number): (multiplier: number) => number
(multiplier: number, multiplicand: number): number
}
Since v2.0.0
multiplyAll
Computes the product of all elements in an iterable collection of numbers.
Example
import * as assert from "node:assert/strict"
import * as Number from "effect/Number"
// Basic products
assert.equal(Number.multiplyAll([2, 3, 4]), 24) // 2 × 3 × 4 = 24
assert.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 collection
assert.equal(Number.multiplyAll([42]), 42)
// Products with negative numbers
assert.equal(Number.multiplyAll([2, -3, 4]), -24) // 2 × (-3) × 4 = -24
assert.equal(Number.multiplyAll([-2, -3]), 6) // (-2) × (-3) = 6
// Zero property - if any element is zero, product is zero
assert.equal(Number.multiplyAll([2, 0, 3]), 0)
// Works with any iterable
assert.equal(Number.multiplyAll(new Set([2, 3, 4])), 24)
// Using with generated sequences
function* range(start: number, end: number) {
for (let i = start; i <= end; i++) yield i
}
// Compute factorial: 5! = 5 × 4 × 3 × 2 × 1 = 120
assert.equal(Number.multiplyAll(range(1, 5)), 120)
Signature
declare const multiplyAll: (collection: Iterable<number>) => number
Since v2.0.0
nextPow2
Returns the next power of 2 greater than or equal to the given number.
- For
positive
inputs, returns the smallest power of 2 that is >= the input - For
zero
, returns 2 - For
negative
inputs, returns NaN (as logarithms of negative numbers are undefined) - For
NaN
input, returns NaN - For
Infinity
, returns Infinity
Example
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 NaN
Signature
declare const nextPow2: (n: number) => number
Since v2.0.0
remainder
Returns the remainder left over when one operand is divided by a second operand.
It always takes the sign of the dividend.
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)
Signature
declare const remainder: {
(divisor: number): (dividend: number) => number
(dividend: number, divisor: number): number
}
Since v2.0.0
round
Returns the number rounded with the given precision.
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)
Signature
declare const round: { (precision: number): (self: number) => number; (self: number, precision: number): number }
Since v3.8.0
sign
Determines the sign of a given number
.
Example
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)
Signature
declare const sign: (n: number) => Ordering
Since v2.0.0
subtract
Performs subtraction in the set of JavaScript numbers.
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 = -1
assert.equal(Number.subtract(10, 5), 5) // 10 - 5 = 5
assert.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 subtractions
assert.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 = a
assert.equal(Number.subtract(42, 0), 42)
// Self-annihilation property: a - a = 0
assert.equal(Number.subtract(42, 42), 0)
// Non-commutative property: a - b ≠ b - a
assert.equal(Number.subtract(5, 3), 2) // 5 - 3 = 2
assert.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))
Signature
declare const subtract: {
(subtrahend: number): (minuend: number) => number
(minuend: number, subtrahend: number): number
}
Since v2.0.0
sum
Performs addition in the set of JavaScript numbers.
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 additions
assert.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 = a
assert.equal(Number.sum(42, 0), 42)
// Commutative property: a + b = b + a
assert.equal(Number.sum(5, 3), Number.sum(3, 5))
Signature
declare const sum: { (that: number): (self: number) => number; (self: number, that: number): number }
Since v2.0.0
sumAll
Computes the sum of all elements in an iterable collection of numbers.
Example
import * as assert from "node:assert/strict"
import * as Number from "effect/Number"
// Basic sums
assert.equal(Number.sumAll([2, 3, 4]), 9) // 2 + 3 + 4 = 9
assert.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 collection
assert.equal(Number.sumAll([42]), 42)
// Sums with negative numbers
assert.equal(Number.sumAll([2, -3, 4]), 3) // 2 + (-3) + 4 = 3
assert.equal(Number.sumAll([-2, -3, -4]), -9) // (-2) + (-3) + (-4) = -9
// Works with any iterable
assert.equal(Number.sumAll(new Set([2, 3, 4])), 9)
// Using with generated sequences
function* 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 = 15
assert.equal(Number.sumAll(range(1, 5)), 15)
// Floating point precision example
assert.equal(
Number.sumAll([0.1, 0.2]),
0.30000000000000004 // Note IEEE 754 precision limitation
)
Signature
declare const sumAll: (collection: Iterable<number>) => number
Since v2.0.0
unsafeDivide
Performs division in the set of JavaScript numbers, but misbehaves for division by zero.
Unlike module:Number.divide
which returns an Option, this function directly returns a number or Infinity
or NaN
.
- If the
divisor
is zero, it returnsInfinity
. - If both the
dividend
and thedivisor
are zero, then it returnsNaN
.
Throws
An {@link module:Number.DivisionByZeroError} if the divisor is zero.
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 = 2
assert.equal(Number.unsafeDivide(-8, 4), -2) // (-8) ÷ 4 = -2
assert.equal(Number.unsafeDivide(-10, -5), 2) // (-10) ÷ (-5) = 2
assert.equal(Number.unsafeDivide(1, 3), 0.3333333333333333)
// Data-last style (pipeable)
assert.equal(
pipe(
10,
Number.unsafeDivide(2) // 10 ÷ 2 = 5
),
5
)
// Chaining multiple divisions
assert.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 division
const safeResult = Number.divide(6, 3) // Option.some(2)
const unsafeResult = Number.unsafeDivide(6, 3) // 2 directly
See
module:Number.divide
- Safe division returning an Option
Signature
declare const unsafeDivide: {
(divisor: number): (dividend: number) => number
(dividend: number, divisor: number): number
}
Since v2.0.0
predicates
between
Checks if a number
is between a minimum
and maximum
value (inclusive).
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)
Signature
declare const between: {
(options: { minimum: number; maximum: number }): (self: number) => boolean
(self: number, options: { minimum: number; maximum: number }): boolean
}
Since v2.0.0
greaterThan
Returns true
if the first argument is greater than the second, otherwise false
.
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)
Signature
declare const greaterThan: { (that: number): (self: number) => boolean; (self: number, that: number): boolean }
Since v2.0.0
greaterThanOrEqualTo
Returns a function that checks if a given number
is greater than or equal to the provided one.
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)
Signature
declare const greaterThanOrEqualTo: { (that: number): (self: number) => boolean; (self: number, that: number): boolean }
Since v2.0.0
lessThan
Returns true
if the first argument is less than the second, otherwise false
.
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)
Signature
declare const lessThan: { (that: number): (self: number) => boolean; (self: number, that: number): boolean }
Since v2.0.0
lessThanOrEqualTo
Returns a function that checks if a given number
is less than or equal to the provided one.
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)
Signature
declare const lessThanOrEqualTo: { (that: number): (self: number) => boolean; (self: number, that: number): boolean }
Since v2.0.0
utils
clamp
Restricts the given number
to be within the range specified by the minimum
and maximum
values.
- If the
number
is less than theminimum
value, the function returns theminimum
value. - If the
number
is greater than themaximum
value, the function returns themaximum
value. - Otherwise, it returns the original
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)
Signature
declare const clamp: {
(options: { minimum: number; maximum: number }): (self: number) => number
(self: number, options: { minimum: number; maximum: number }): number
}
Since v2.0.0
max
Returns the maximum between two number
s.
Example
import * as assert from "node:assert/strict"
import { max } from "effect/Number"
assert.equal(max(2, 3), 3)
Signature
declare const max: { (that: number): (self: number) => number; (self: number, that: number): number }
Since v2.0.0
min
Returns the minimum between two number
s.
Example
import * as assert from "node:assert/strict"
import { min } from "effect/Number"
assert.equal(min(2, 3), 2)
Signature
declare const min: { (that: number): (self: number) => number; (self: number, that: number): number }
Since v2.0.0
negate
Returns the additive inverse of a number, effectively negating it.
Example
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
)
Signature
declare const negate: (n: number) => number
Since v3.14.6