effect 3.14.11 → 3.14.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/BigDecimal.js +3 -0
- package/dist/cjs/BigDecimal.js.map +1 -1
- package/dist/cjs/BigInt.js +3 -0
- package/dist/cjs/BigInt.js.map +1 -1
- package/dist/cjs/JSONSchema.js +24 -10
- package/dist/cjs/JSONSchema.js.map +1 -1
- package/dist/cjs/Number.js +650 -196
- package/dist/cjs/Number.js.map +1 -1
- package/dist/cjs/ParseResult.js +3 -1
- package/dist/cjs/ParseResult.js.map +1 -1
- package/dist/cjs/Schema.js +4 -2
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/BigDecimal.d.ts +3 -0
- package/dist/dts/BigDecimal.d.ts.map +1 -1
- package/dist/dts/BigInt.d.ts +3 -0
- package/dist/dts/BigInt.d.ts.map +1 -1
- package/dist/dts/JSONSchema.d.ts.map +1 -1
- package/dist/dts/Number.d.ts +866 -421
- package/dist/dts/Number.d.ts.map +1 -1
- package/dist/dts/ParseResult.d.ts.map +1 -1
- package/dist/dts/Schema.d.ts +1 -3
- package/dist/dts/Schema.d.ts.map +1 -1
- package/dist/dts/index.d.ts +98 -3
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/esm/BigDecimal.js +3 -0
- package/dist/esm/BigDecimal.js.map +1 -1
- package/dist/esm/BigInt.js +3 -0
- package/dist/esm/BigInt.js.map +1 -1
- package/dist/esm/JSONSchema.js +24 -10
- package/dist/esm/JSONSchema.js.map +1 -1
- package/dist/esm/Number.js +645 -192
- package/dist/esm/Number.js.map +1 -1
- package/dist/esm/ParseResult.js +2 -1
- package/dist/esm/ParseResult.js.map +1 -1
- package/dist/esm/Schema.js +4 -2
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/index.js +98 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +1 -1
- package/src/BigDecimal.ts +3 -0
- package/src/BigInt.ts +3 -0
- package/src/JSONSchema.ts +20 -7
- package/src/Number.ts +913 -475
- package/src/ParseResult.ts +2 -1
- package/src/Schema.ts +11 -8
- package/src/index.ts +98 -3
- package/src/internal/version.ts +1 -1
package/src/Number.ts
CHANGED
|
@@ -1,534 +1,977 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* # Number
|
|
3
|
+
*
|
|
4
|
+
* This module provides utility functions and type class instances for working
|
|
5
|
+
* with the `number` type in TypeScript. It includes functions for basic
|
|
6
|
+
* arithmetic operations, as well as type class instances for `Equivalence` and
|
|
7
|
+
* `Order`.
|
|
8
|
+
*
|
|
9
|
+
* ## Operations Reference
|
|
10
|
+
*
|
|
11
|
+
* | Category | Operation | Description | Domain | Co-domain |
|
|
12
|
+
* | ------------ | ------------------------------------------ | ------------------------------------------------------- | ------------------------------ | --------------------- |
|
|
13
|
+
* | constructors | {@link module:Number.parse} | Safely parses a string to a number | `string` | `Option<number>` |
|
|
14
|
+
* | | | | | |
|
|
15
|
+
* | math | {@link module:Number.sum} | Adds two numbers | `number`, `number` | `number` |
|
|
16
|
+
* | math | {@link module:Number.sumAll} | Sums all numbers in a collection | `Iterable<number>` | `number` |
|
|
17
|
+
* | math | {@link module:Number.subtract} | Subtracts one number from another | `number`, `number` | `number` |
|
|
18
|
+
* | math | {@link module:Number.multiply} | Multiplies two numbers | `number`, `number` | `number` |
|
|
19
|
+
* | math | {@link module:Number.multiplyAll} | Multiplies all numbers in a collection | `Iterable<number>` | `number` |
|
|
20
|
+
* | math | {@link module:Number.divide} | Safely divides handling division by zero | `number`, `number` | `Option<number>` |
|
|
21
|
+
* | math | {@link module:Number.unsafeDivide} | Divides but misbehaves for division by zero | `number`, `number` | `number` |
|
|
22
|
+
* | math | {@link module:Number.remainder} | Calculates remainder of division | `number`, `number` | `number` |
|
|
23
|
+
* | math | {@link module:Number.increment} | Adds 1 to a number | `number` | `number` |
|
|
24
|
+
* | math | {@link module:Number.decrement} | Subtracts 1 from a number | `number` | `number` |
|
|
25
|
+
* | math | {@link module:Number.sign} | Determines the sign of a number | `number` | `Ordering` |
|
|
26
|
+
* | math | {@link module:Number.nextPow2} | Finds the next power of 2 | `number` | `number` |
|
|
27
|
+
* | math | {@link module:Number.round} | Rounds a number with specified precision | `number`, `number` | `number` |
|
|
28
|
+
* | | | | | |
|
|
29
|
+
* | predicates | {@link module:Number.between} | Checks if a number is in a range | `number`, `{minimum, maximum}` | `boolean` |
|
|
30
|
+
* | predicates | {@link module:Number.lessThan} | Checks if one number is less than another | `number`, `number` | `boolean` |
|
|
31
|
+
* | predicates | {@link module:Number.lessThanOrEqualTo} | Checks if one number is less than or equal | `number`, `number` | `boolean` |
|
|
32
|
+
* | predicates | {@link module:Number.greaterThan} | Checks if one number is greater than another | `number`, `number` | `boolean` |
|
|
33
|
+
* | predicates | {@link module:Number.greaterThanOrEqualTo} | Checks if one number is greater or equal | `number`, `number` | `boolean` |
|
|
34
|
+
* | | | | | |
|
|
35
|
+
* | guards | {@link module:Number.isNumber} | Type guard for JavaScript numbers | `unknown` | `boolean` |
|
|
36
|
+
* | | | | | |
|
|
37
|
+
* | comparison | {@link module:Number.min} | Returns the minimum of two numbers | `number`, `number` | `number` |
|
|
38
|
+
* | comparison | {@link module:Number.max} | Returns the maximum of two numbers | `number`, `number` | `number` |
|
|
39
|
+
* | comparison | {@link module:Number.clamp} | Restricts a number to a range | `number`, `{minimum, maximum}` | `number` |
|
|
40
|
+
* | | | | | |
|
|
41
|
+
* | instances | {@link module:Number.Equivalence} | Equivalence instance for numbers | | `Equivalence<number>` |
|
|
42
|
+
* | instances | {@link module:Number.Order} | Order instance for numbers | | `Order<number>` |
|
|
43
|
+
* | | | | | |
|
|
44
|
+
* | errors | {@link module:Number.DivisionByZeroError} | Error thrown by unsafeDivide | | |
|
|
45
|
+
*
|
|
46
|
+
* ## Composition Patterns and Type Safety
|
|
47
|
+
*
|
|
48
|
+
* When building function pipelines, understanding how types flow through
|
|
49
|
+
* operations is critical:
|
|
50
|
+
*
|
|
51
|
+
* ### Composing with type-preserving operations
|
|
52
|
+
*
|
|
53
|
+
* Most operations in this module are type-preserving (`number → number`),
|
|
54
|
+
* making them easily composable in pipelines:
|
|
5
55
|
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { pipe } from "effect"
|
|
58
|
+
* import * as Number from "effect/Number"
|
|
59
|
+
*
|
|
60
|
+
* const result = pipe(
|
|
61
|
+
* 10,
|
|
62
|
+
* Number.increment, // number → number
|
|
63
|
+
* Number.multiply(2), // number → number
|
|
64
|
+
* Number.round(1) // number → number
|
|
65
|
+
* ) // Result: number (21)
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* ### Working with Option results
|
|
69
|
+
*
|
|
70
|
+
* Operations that might fail (like division by zero) return Option types and
|
|
71
|
+
* require Option combinators:
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { pipe, Option } from "effect"
|
|
75
|
+
* import * as Number from "effect/Number"
|
|
76
|
+
*
|
|
77
|
+
* const result = pipe(
|
|
78
|
+
* 10,
|
|
79
|
+
* Number.divide(0), // number → Option<number>
|
|
80
|
+
* Option.getOrElse(() => 0) // Option<number> → number
|
|
81
|
+
* ) // Result: number (0)
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* ### Composition best practices
|
|
85
|
+
*
|
|
86
|
+
* - Chain type-preserving operations for maximum composability
|
|
87
|
+
* - Use Option combinators when working with potentially failing operations
|
|
88
|
+
* - Consider using Effect for operations that might fail with specific errors
|
|
89
|
+
* - Remember that all operations maintain JavaScript's floating-point precision
|
|
90
|
+
* limitations
|
|
91
|
+
*
|
|
92
|
+
* @module Number
|
|
6
93
|
* @since 2.0.0
|
|
94
|
+
* @see {@link module:BigInt} for more similar operations on `bigint` types
|
|
95
|
+
* @see {@link module:BigDecimal} for more similar operations on `BigDecimal` types
|
|
7
96
|
*/
|
|
97
|
+
|
|
8
98
|
import * as equivalence from "./Equivalence.js"
|
|
9
99
|
import { dual } from "./Function.js"
|
|
10
100
|
import * as option from "./internal/option.js"
|
|
101
|
+
import * as _Iterable from "./Iterable.js"
|
|
11
102
|
import type { Option } from "./Option.js"
|
|
12
103
|
import * as order from "./Order.js"
|
|
13
104
|
import type { Ordering } from "./Ordering.js"
|
|
14
105
|
import * as predicate from "./Predicate.js"
|
|
15
106
|
|
|
16
107
|
/**
|
|
17
|
-
*
|
|
108
|
+
* Type guard that tests if a value is a member of the set of JavaScript
|
|
109
|
+
* numbers.
|
|
18
110
|
*
|
|
111
|
+
* @memberof Number
|
|
112
|
+
* @since 2.0.0
|
|
113
|
+
* @category guards
|
|
19
114
|
* @example
|
|
20
|
-
* ```ts
|
|
21
|
-
* import * as assert from "node:assert"
|
|
22
|
-
* import { isNumber } from "effect/Number"
|
|
23
115
|
*
|
|
24
|
-
*
|
|
25
|
-
* assert
|
|
116
|
+
* ```ts
|
|
117
|
+
* import * as assert from "node:assert/strict"
|
|
118
|
+
* import * as Number from "effect/Number"
|
|
119
|
+
*
|
|
120
|
+
* // Regular numbers
|
|
121
|
+
* assert.equal(Number.isNumber(2), true)
|
|
122
|
+
* assert.equal(Number.isNumber(-3.14), true)
|
|
123
|
+
* assert.equal(Number.isNumber(0), true)
|
|
124
|
+
*
|
|
125
|
+
* // Special numeric values
|
|
126
|
+
* assert.equal(Number.isNumber(Infinity), true)
|
|
127
|
+
* assert.equal(Number.isNumber(NaN), true)
|
|
128
|
+
*
|
|
129
|
+
* // Non-number values
|
|
130
|
+
* assert.equal(Number.isNumber("2"), false)
|
|
131
|
+
* assert.equal(Number.isNumber(true), false)
|
|
132
|
+
* assert.equal(Number.isNumber(null), false)
|
|
133
|
+
* assert.equal(Number.isNumber(undefined), false)
|
|
134
|
+
* assert.equal(Number.isNumber({}), false)
|
|
135
|
+
* assert.equal(Number.isNumber([]), false)
|
|
136
|
+
*
|
|
137
|
+
* // Using as a type guard in conditionals
|
|
138
|
+
* function processValue(value: unknown): string {
|
|
139
|
+
* if (Number.isNumber(value)) {
|
|
140
|
+
* // TypeScript now knows 'value' is a number
|
|
141
|
+
* return `Numeric value: ${value.toFixed(2)}`
|
|
142
|
+
* }
|
|
143
|
+
* return "Not a number"
|
|
144
|
+
* }
|
|
145
|
+
*
|
|
146
|
+
* assert.strictEqual(processValue(42), "Numeric value: 42.00")
|
|
147
|
+
* assert.strictEqual(processValue("hello"), "Not a number")
|
|
148
|
+
*
|
|
149
|
+
* // Filtering for numbers in an array
|
|
150
|
+
* const mixed = [1, "two", 3, false, 5]
|
|
151
|
+
* const onlyNumbers = mixed.filter(Number.isNumber)
|
|
152
|
+
* assert.equal(onlyNumbers, [1, 3, 5])
|
|
26
153
|
* ```
|
|
27
154
|
*
|
|
28
|
-
* @
|
|
29
|
-
*
|
|
155
|
+
* @param input - The value to test for membership in the set of JavaScript
|
|
156
|
+
* numbers
|
|
157
|
+
*
|
|
158
|
+
* @returns `true` if the input is a JavaScript number, `false` otherwise
|
|
30
159
|
*/
|
|
31
160
|
export const isNumber: (input: unknown) => input is number = predicate.isNumber
|
|
32
161
|
|
|
33
162
|
/**
|
|
34
|
-
*
|
|
163
|
+
* Returns the additive inverse of a number, effectively negating it.
|
|
35
164
|
*
|
|
165
|
+
* @memberof Number
|
|
166
|
+
* @since 3.14.6
|
|
36
167
|
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* import * as assert from "node:assert"
|
|
39
|
-
* import { sum } from "effect/Number"
|
|
40
168
|
*
|
|
41
|
-
*
|
|
169
|
+
* ```ts
|
|
170
|
+
* import * as assert from "node:assert/strict"
|
|
171
|
+
* import { pipe } from "effect"
|
|
172
|
+
* import * as Number from "effect/Number"
|
|
173
|
+
*
|
|
174
|
+
* assert.equal(
|
|
175
|
+
* Number.negate(5), //
|
|
176
|
+
* -5
|
|
177
|
+
* )
|
|
178
|
+
*
|
|
179
|
+
* assert.equal(
|
|
180
|
+
* Number.negate(-5), //
|
|
181
|
+
* 5
|
|
182
|
+
* )
|
|
183
|
+
*
|
|
184
|
+
* assert.equal(
|
|
185
|
+
* Number.negate(0), //
|
|
186
|
+
* 0
|
|
187
|
+
* )
|
|
42
188
|
* ```
|
|
43
189
|
*
|
|
44
|
-
* @
|
|
190
|
+
* @param n - The number value to be negated.
|
|
191
|
+
*
|
|
192
|
+
* @returns The negated number value.
|
|
193
|
+
*/
|
|
194
|
+
export const negate = (n: number): number => multiply(n, -1)
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Performs addition in the set of JavaScript numbers.
|
|
198
|
+
*
|
|
199
|
+
* @memberof Number
|
|
45
200
|
* @since 2.0.0
|
|
201
|
+
* @category math
|
|
202
|
+
* @example
|
|
203
|
+
*
|
|
204
|
+
* ```ts
|
|
205
|
+
* import * as assert from "node:assert/strict"
|
|
206
|
+
* import { pipe } from "effect"
|
|
207
|
+
* import * as Number from "effect/Number"
|
|
208
|
+
*
|
|
209
|
+
* // Data-first style (direct application)
|
|
210
|
+
* assert.equal(Number.sum(2, 3), 5)
|
|
211
|
+
* assert.equal(Number.sum(-10, 5), -5)
|
|
212
|
+
* assert.equal(Number.sum(0.1, 0.2), 0.30000000000000004) // Note: floating-point precision limitation
|
|
213
|
+
*
|
|
214
|
+
* // Data-last style (pipeable)
|
|
215
|
+
* assert.equal(
|
|
216
|
+
* pipe(
|
|
217
|
+
* 10,
|
|
218
|
+
* Number.sum(5) // 10 + 5 = 15
|
|
219
|
+
* ),
|
|
220
|
+
* 15
|
|
221
|
+
* )
|
|
222
|
+
*
|
|
223
|
+
* // Chaining multiple additions
|
|
224
|
+
* assert.equal(
|
|
225
|
+
* pipe(
|
|
226
|
+
* 1,
|
|
227
|
+
* Number.sum(2), // 1 + 2 = 3
|
|
228
|
+
* Number.sum(3), // 3 + 3 = 6
|
|
229
|
+
* Number.sum(4) // 6 + 4 = 10
|
|
230
|
+
* ),
|
|
231
|
+
* 10
|
|
232
|
+
* )
|
|
233
|
+
*
|
|
234
|
+
* // Identity property: a + 0 = a
|
|
235
|
+
* assert.equal(Number.sum(42, 0), 42)
|
|
236
|
+
*
|
|
237
|
+
* // Commutative property: a + b = b + a
|
|
238
|
+
* assert.equal(Number.sum(5, 3), Number.sum(3, 5))
|
|
239
|
+
* ```
|
|
46
240
|
*/
|
|
47
241
|
export const sum: {
|
|
48
242
|
/**
|
|
49
|
-
*
|
|
243
|
+
* Returns a function that adds a specified number to its argument.
|
|
50
244
|
*
|
|
51
|
-
* @
|
|
52
|
-
* ```ts
|
|
53
|
-
* import * as assert from "node:assert"
|
|
54
|
-
* import { sum } from "effect/Number"
|
|
245
|
+
* @param that - The number to add to the input of the resulting function
|
|
55
246
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* @category math
|
|
60
|
-
* @since 2.0.0
|
|
247
|
+
* @returns A function that takes a number and returns the sum of that number
|
|
248
|
+
* and `that`
|
|
61
249
|
*/
|
|
62
250
|
(that: number): (self: number) => number
|
|
251
|
+
|
|
63
252
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```ts
|
|
68
|
-
* import * as assert from "node:assert"
|
|
69
|
-
* import { sum } from "effect/Number"
|
|
253
|
+
* Adds two numbers together.
|
|
70
254
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
255
|
+
* @param self - The first addend
|
|
256
|
+
* @param that - The second addend
|
|
73
257
|
*
|
|
74
|
-
* @
|
|
75
|
-
* @since 2.0.0
|
|
258
|
+
* @returns The sum of the two numbers
|
|
76
259
|
*/
|
|
77
260
|
(self: number, that: number): number
|
|
78
261
|
} = dual(2, (self: number, that: number): number => self + that)
|
|
79
262
|
|
|
80
263
|
/**
|
|
81
|
-
*
|
|
264
|
+
* Computes the sum of all elements in an iterable collection of numbers.
|
|
82
265
|
*
|
|
266
|
+
* @memberof Number
|
|
267
|
+
* @since 2.0.0
|
|
268
|
+
* @category math
|
|
83
269
|
* @example
|
|
270
|
+
*
|
|
84
271
|
* ```ts
|
|
85
|
-
* import * as assert from "node:assert"
|
|
86
|
-
* import
|
|
272
|
+
* import * as assert from "node:assert/strict"
|
|
273
|
+
* import * as Number from "effect/Number"
|
|
274
|
+
*
|
|
275
|
+
* // Basic sums
|
|
276
|
+
* assert.equal(Number.sumAll([2, 3, 4]), 9) // 2 + 3 + 4 = 9
|
|
277
|
+
* assert.equal(Number.sumAll([1.1, 2.2, 3.3]), 6.6) // 1.1 + 2.2 + 3.3 = 6.6
|
|
278
|
+
*
|
|
279
|
+
* // Empty collection returns the additive identity (0)
|
|
280
|
+
* assert.equal(Number.sumAll([]), 0)
|
|
281
|
+
*
|
|
282
|
+
* // Single element collection
|
|
283
|
+
* assert.equal(Number.sumAll([42]), 42)
|
|
284
|
+
*
|
|
285
|
+
* // Sums with negative numbers
|
|
286
|
+
* assert.equal(Number.sumAll([2, -3, 4]), 3) // 2 + (-3) + 4 = 3
|
|
287
|
+
* assert.equal(Number.sumAll([-2, -3, -4]), -9) // (-2) + (-3) + (-4) = -9
|
|
288
|
+
*
|
|
289
|
+
* // Works with any iterable
|
|
290
|
+
* assert.equal(Number.sumAll(new Set([2, 3, 4])), 9)
|
|
291
|
+
*
|
|
292
|
+
* // Using with generated sequences
|
|
293
|
+
* function* range(start: number, end: number) {
|
|
294
|
+
* for (let i = start; i <= end; i++) yield i
|
|
295
|
+
* }
|
|
87
296
|
*
|
|
88
|
-
*
|
|
297
|
+
* // Compute sum of first 5 natural numbers: 1 + 2 + 3 + 4 + 5 = 15
|
|
298
|
+
* assert.equal(Number.sumAll(range(1, 5)), 15)
|
|
299
|
+
*
|
|
300
|
+
* // Floating point precision example
|
|
301
|
+
* assert.equal(
|
|
302
|
+
* Number.sumAll([0.1, 0.2]),
|
|
303
|
+
* 0.30000000000000004 // Note IEEE 754 precision limitation
|
|
304
|
+
* )
|
|
89
305
|
* ```
|
|
90
306
|
*
|
|
91
|
-
* @
|
|
307
|
+
* @param collection - An `iterable` containing the `numbers` to sum
|
|
308
|
+
*
|
|
309
|
+
* @returns The sum of all numbers in the collection, or 0 if the collection is
|
|
310
|
+
* empty
|
|
311
|
+
*/
|
|
312
|
+
export const sumAll = (collection: Iterable<number>): number => _Iterable.reduce(collection, 0, sum)
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Performs subtraction in the set of JavaScript numbers.
|
|
316
|
+
*
|
|
317
|
+
* @memberof Number
|
|
92
318
|
* @since 2.0.0
|
|
319
|
+
* @category math
|
|
320
|
+
* @example
|
|
321
|
+
*
|
|
322
|
+
* ```ts
|
|
323
|
+
* import * as assert from "node:assert/strict"
|
|
324
|
+
* import { pipe } from "effect"
|
|
325
|
+
* import * as Number from "effect/Number"
|
|
326
|
+
*
|
|
327
|
+
* // Data-first style (direct application)
|
|
328
|
+
* assert.equal(Number.subtract(2, 3), -1) // 2 - 3 = -1
|
|
329
|
+
* assert.equal(Number.subtract(10, 5), 5) // 10 - 5 = 5
|
|
330
|
+
* assert.equal(Number.subtract(0.3, 0.1), 0.19999999999999998) // Note: floating-point precision limitation
|
|
331
|
+
*
|
|
332
|
+
* // Data-last style (pipeable)
|
|
333
|
+
* assert.equal(
|
|
334
|
+
* pipe(
|
|
335
|
+
* 10,
|
|
336
|
+
* Number.subtract(5) // 10 - 5 = 5
|
|
337
|
+
* ),
|
|
338
|
+
* 5
|
|
339
|
+
* )
|
|
340
|
+
*
|
|
341
|
+
* // Chaining multiple subtractions
|
|
342
|
+
* assert.equal(
|
|
343
|
+
* pipe(
|
|
344
|
+
* 20,
|
|
345
|
+
* Number.subtract(5), // 20 - 5 = 15
|
|
346
|
+
* Number.subtract(3), // 15 - 3 = 12
|
|
347
|
+
* Number.subtract(2) // 12 - 2 = 10
|
|
348
|
+
* ),
|
|
349
|
+
* 10
|
|
350
|
+
* )
|
|
351
|
+
*
|
|
352
|
+
* // Right identity property: a - 0 = a
|
|
353
|
+
* assert.equal(Number.subtract(42, 0), 42)
|
|
354
|
+
*
|
|
355
|
+
* // Self-annihilation property: a - a = 0
|
|
356
|
+
* assert.equal(Number.subtract(42, 42), 0)
|
|
357
|
+
*
|
|
358
|
+
* // Non-commutative property: a - b ≠ b - a
|
|
359
|
+
* assert.equal(Number.subtract(5, 3), 2) // 5 - 3 = 2
|
|
360
|
+
* assert.equal(Number.subtract(3, 5), -2) // 3 - 5 = -2
|
|
361
|
+
*
|
|
362
|
+
* // Inverse relation: a - b = -(b - a)
|
|
363
|
+
* assert.equal(Number.subtract(5, 3), -Number.subtract(3, 5))
|
|
364
|
+
* ```
|
|
93
365
|
*/
|
|
94
|
-
export const
|
|
366
|
+
export const subtract: {
|
|
95
367
|
/**
|
|
96
|
-
*
|
|
368
|
+
* Returns a function that subtracts a specified number from its argument.
|
|
97
369
|
*
|
|
98
|
-
* @
|
|
99
|
-
*
|
|
100
|
-
* import * as assert from "node:assert"
|
|
101
|
-
* import { multiply } from "effect/Number"
|
|
370
|
+
* @param subtrahend - The number to subtract from the input of the resulting
|
|
371
|
+
* function
|
|
102
372
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* @category math
|
|
107
|
-
* @since 2.0.0
|
|
373
|
+
* @returns A function that takes a minuend and returns the difference of
|
|
374
|
+
* subtracting the subtrahend from it
|
|
108
375
|
*/
|
|
109
|
-
(
|
|
376
|
+
(subtrahend: number): (minuend: number) => number
|
|
377
|
+
|
|
110
378
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* ```ts
|
|
115
|
-
* import * as assert from "node:assert"
|
|
116
|
-
* import { multiply } from "effect/Number"
|
|
379
|
+
* Subtracts the subtrahend from the minuend and returns the difference.
|
|
117
380
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
381
|
+
* @param minuend - The number from which another number is to be subtracted
|
|
382
|
+
* @param subtrahend - The number to subtract from the minuend
|
|
120
383
|
*
|
|
121
|
-
* @
|
|
122
|
-
* @since 2.0.0
|
|
384
|
+
* @returns The difference of the minuend minus the subtrahend
|
|
123
385
|
*/
|
|
124
|
-
(
|
|
125
|
-
} = dual(
|
|
386
|
+
(minuend: number, subtrahend: number): number
|
|
387
|
+
} = dual(
|
|
388
|
+
2,
|
|
389
|
+
(minuend: number, subtrahend: number): number => minuend - subtrahend
|
|
390
|
+
)
|
|
126
391
|
|
|
127
392
|
/**
|
|
128
|
-
*
|
|
393
|
+
* Performs **multiplication** in the set of JavaScript numbers.
|
|
129
394
|
*
|
|
395
|
+
* @memberof Number
|
|
396
|
+
* @since 2.0.0
|
|
397
|
+
* @category math
|
|
130
398
|
* @example
|
|
131
|
-
* ```ts
|
|
132
|
-
* import * as assert from "node:assert"
|
|
133
|
-
* import { subtract } from "effect/Number"
|
|
134
399
|
*
|
|
135
|
-
*
|
|
400
|
+
* ```ts
|
|
401
|
+
* import * as assert from "node:assert/strict"
|
|
402
|
+
* import { pipe } from "effect"
|
|
403
|
+
* import * as Number from "effect/Number"
|
|
404
|
+
*
|
|
405
|
+
* // Data-first style (direct application)
|
|
406
|
+
* assert.equal(Number.multiply(2, 3), 6) // 2 × 3 = 6
|
|
407
|
+
* assert.equal(Number.multiply(-4, 5), -20) // (-4) × 5 = -20
|
|
408
|
+
* assert.equal(Number.multiply(-3, -2), 6) // (-3) × (-2) = 6
|
|
409
|
+
* assert.equal(Number.multiply(0.1, 0.2), 0.020000000000000004) // Note: floating-point precision limitation
|
|
410
|
+
*
|
|
411
|
+
* // Data-last style (pipeable)
|
|
412
|
+
* assert.equal(
|
|
413
|
+
* pipe(
|
|
414
|
+
* 10,
|
|
415
|
+
* Number.multiply(5) // 10 × 5 = 50
|
|
416
|
+
* ),
|
|
417
|
+
* 50
|
|
418
|
+
* )
|
|
419
|
+
*
|
|
420
|
+
* // Chaining multiple multiplications
|
|
421
|
+
* assert.equal(
|
|
422
|
+
* pipe(
|
|
423
|
+
* 2,
|
|
424
|
+
* Number.multiply(3), // 2 × 3 = 6
|
|
425
|
+
* Number.multiply(4), // 6 × 4 = 24
|
|
426
|
+
* Number.multiply(0.5) // 24 × 0.5 = 12
|
|
427
|
+
* ),
|
|
428
|
+
* 12
|
|
429
|
+
* )
|
|
430
|
+
*
|
|
431
|
+
* // Identity property: a × 1 = a
|
|
432
|
+
* assert.equal(Number.multiply(42, 1), 42)
|
|
433
|
+
*
|
|
434
|
+
* // Zero property: a × 0 = 0
|
|
435
|
+
* assert.equal(Number.multiply(42, 0), 0)
|
|
436
|
+
*
|
|
437
|
+
* // Commutative property: a × b = b × a
|
|
438
|
+
* assert.equal(Number.multiply(5, 3), Number.multiply(3, 5))
|
|
439
|
+
*
|
|
440
|
+
* // Associative property: (a × b) × c = a × (b × c)
|
|
441
|
+
* const a = 2,
|
|
442
|
+
* b = 3,
|
|
443
|
+
* c = 4
|
|
444
|
+
* assert.equal(
|
|
445
|
+
* Number.multiply(Number.multiply(a, b), c),
|
|
446
|
+
* Number.multiply(a, Number.multiply(b, c))
|
|
447
|
+
* )
|
|
136
448
|
* ```
|
|
137
|
-
*
|
|
138
|
-
* @category math
|
|
139
|
-
* @since 2.0.0
|
|
140
449
|
*/
|
|
141
|
-
export const
|
|
450
|
+
export const multiply: {
|
|
142
451
|
/**
|
|
143
|
-
*
|
|
452
|
+
* Returns a function that multiplies a specified number with its argument.
|
|
144
453
|
*
|
|
145
|
-
* @
|
|
146
|
-
*
|
|
147
|
-
* import * as assert from "node:assert"
|
|
148
|
-
* import { subtract } from "effect/Number"
|
|
454
|
+
* @param multiplicand - The number to multiply with the input of the
|
|
455
|
+
* resulting function
|
|
149
456
|
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* @category math
|
|
154
|
-
* @since 2.0.0
|
|
457
|
+
* @returns A function that takes a multiplier and returns the product of that
|
|
458
|
+
* multiplier and the multiplicand
|
|
155
459
|
*/
|
|
156
|
-
(
|
|
460
|
+
(multiplicand: number): (multiplier: number) => number
|
|
461
|
+
|
|
157
462
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* @example
|
|
161
|
-
* ```ts
|
|
162
|
-
* import * as assert from "node:assert"
|
|
163
|
-
* import { subtract } from "effect/Number"
|
|
463
|
+
* Multiplies two numbers together.
|
|
164
464
|
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
465
|
+
* @param multiplier - The first factor
|
|
466
|
+
* @param multiplicand - The second factor
|
|
167
467
|
*
|
|
168
|
-
* @
|
|
169
|
-
* @since 2.0.0
|
|
468
|
+
* @returns The product of the two numbers
|
|
170
469
|
*/
|
|
171
|
-
(
|
|
172
|
-
} = dual(
|
|
470
|
+
(multiplier: number, multiplicand: number): number
|
|
471
|
+
} = dual(
|
|
472
|
+
2,
|
|
473
|
+
(multiplier: number, multiplicand: number): number => multiplier * multiplicand
|
|
474
|
+
)
|
|
173
475
|
|
|
174
476
|
/**
|
|
175
|
-
*
|
|
477
|
+
* Computes the product of all elements in an iterable collection of numbers.
|
|
176
478
|
*
|
|
479
|
+
* @memberof Number
|
|
480
|
+
* @since 2.0.0
|
|
481
|
+
* @category math
|
|
177
482
|
* @example
|
|
483
|
+
*
|
|
178
484
|
* ```ts
|
|
179
|
-
* import * as assert from "node:assert"
|
|
180
|
-
* import
|
|
485
|
+
* import * as assert from "node:assert/strict"
|
|
486
|
+
* import * as Number from "effect/Number"
|
|
487
|
+
*
|
|
488
|
+
* // Basic products
|
|
489
|
+
* assert.equal(Number.multiplyAll([2, 3, 4]), 24) // 2 × 3 × 4 = 24
|
|
490
|
+
* assert.equal(Number.multiplyAll([1.5, 2, 3]), 9) // 1.5 × 2 × 3 = 9
|
|
491
|
+
*
|
|
492
|
+
* // Empty collection returns the multiplicative identity (1)
|
|
493
|
+
* assert.equal(Number.multiplyAll([]), 1)
|
|
494
|
+
*
|
|
495
|
+
* // Single element collection
|
|
496
|
+
* assert.equal(Number.multiplyAll([42]), 42)
|
|
497
|
+
*
|
|
498
|
+
* // Products with negative numbers
|
|
499
|
+
* assert.equal(Number.multiplyAll([2, -3, 4]), -24) // 2 × (-3) × 4 = -24
|
|
500
|
+
* assert.equal(Number.multiplyAll([-2, -3]), 6) // (-2) × (-3) = 6
|
|
181
501
|
*
|
|
182
|
-
*
|
|
183
|
-
* assert.
|
|
502
|
+
* // Zero property - if any element is zero, product is zero
|
|
503
|
+
* assert.equal(Number.multiplyAll([2, 0, 3]), 0)
|
|
504
|
+
*
|
|
505
|
+
* // Works with any iterable
|
|
506
|
+
* assert.equal(Number.multiplyAll(new Set([2, 3, 4])), 24)
|
|
507
|
+
*
|
|
508
|
+
* // Using with generated sequences
|
|
509
|
+
* function* range(start: number, end: number) {
|
|
510
|
+
* for (let i = start; i <= end; i++) yield i
|
|
511
|
+
* }
|
|
512
|
+
*
|
|
513
|
+
* // Compute factorial: 5! = 5 × 4 × 3 × 2 × 1 = 120
|
|
514
|
+
* assert.equal(Number.multiplyAll(range(1, 5)), 120)
|
|
184
515
|
* ```
|
|
185
516
|
*
|
|
186
|
-
* @
|
|
517
|
+
* @param collection - An `iterable` containing the `numbers` to multiply
|
|
518
|
+
*
|
|
519
|
+
* @returns The product of all numbers in the collection, or 1 if the collection
|
|
520
|
+
* is empty
|
|
521
|
+
*/
|
|
522
|
+
export const multiplyAll = (collection: Iterable<number>): number => {
|
|
523
|
+
let out = 1
|
|
524
|
+
for (const n of collection) {
|
|
525
|
+
if (n === 0) {
|
|
526
|
+
return 0
|
|
527
|
+
}
|
|
528
|
+
out *= n
|
|
529
|
+
}
|
|
530
|
+
return out
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Performs division in the set of JavaScript numbers, returning the result
|
|
535
|
+
* wrapped in an `Option` to handle division by zero.
|
|
536
|
+
*
|
|
537
|
+
* @memberof Number
|
|
187
538
|
* @since 2.0.0
|
|
539
|
+
* @category math
|
|
540
|
+
* @example
|
|
541
|
+
*
|
|
542
|
+
* ```ts
|
|
543
|
+
* import * as assert from "node:assert/strict"
|
|
544
|
+
* import { pipe, Option } from "effect"
|
|
545
|
+
* import * as Number from "effect/Number"
|
|
546
|
+
*
|
|
547
|
+
* // Data-first style (direct application)
|
|
548
|
+
* assert.equal(Number.divide(6, 3), Option.some(2)) // 6 ÷ 3 = 2
|
|
549
|
+
* assert.equal(Number.divide(-8, 4), Option.some(-2)) // (-8) ÷ 4 = -2
|
|
550
|
+
* assert.equal(Number.divide(-10, -5), Option.some(2)) // (-10) ÷ (-5) = 2
|
|
551
|
+
* assert.equal(Number.divide(1, 3), Option.some(0.3333333333333333)) // Note: floating-point approximation
|
|
552
|
+
*
|
|
553
|
+
* // Handling division by zero
|
|
554
|
+
* assert.equal(Number.divide(6, 0), Option.none()) // 6 ÷ 0 is undefined
|
|
555
|
+
*
|
|
556
|
+
* // Data-last style (pipeable)
|
|
557
|
+
* assert.equal(
|
|
558
|
+
* pipe(
|
|
559
|
+
* 10,
|
|
560
|
+
* Number.divide(2) // 10 ÷ 2 = 5
|
|
561
|
+
* ),
|
|
562
|
+
* Option.some(5)
|
|
563
|
+
* )
|
|
564
|
+
*
|
|
565
|
+
* // Chaining multiple divisions using Option combinators
|
|
566
|
+
* assert.equal(
|
|
567
|
+
* pipe(
|
|
568
|
+
* Option.some(24),
|
|
569
|
+
* Option.flatMap((n) => Number.divide(n, 2)), // 24 ÷ 2 = 12
|
|
570
|
+
* Option.flatMap(Number.divide(3)), // 12 ÷ 3 = 4
|
|
571
|
+
* Option.flatMap(Number.divide(2)) // 4 ÷ 2 = 2
|
|
572
|
+
* ),
|
|
573
|
+
* Option.some(2)
|
|
574
|
+
* )
|
|
575
|
+
*
|
|
576
|
+
* // Division-by-one property: a ÷ 1 = a
|
|
577
|
+
* assert.equal(Number.divide(42, 1), Option.some(42))
|
|
578
|
+
*
|
|
579
|
+
* // Self-division property: a ÷ a = 1 (for a ≠ 0)
|
|
580
|
+
* assert.equal(Number.divide(42, 42), Option.some(1))
|
|
581
|
+
*
|
|
582
|
+
* // Non-commutative property: a ÷ b ≠ b ÷ a
|
|
583
|
+
* assert.notDeepStrictEqual(
|
|
584
|
+
* Number.divide(6, 3), // 6 ÷ 3 = 2
|
|
585
|
+
* Number.divide(3, 6) // 3 ÷ 6 = 0.5
|
|
586
|
+
* )
|
|
587
|
+
* ```
|
|
188
588
|
*/
|
|
189
589
|
export const divide: {
|
|
190
590
|
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```ts
|
|
195
|
-
* import * as assert from "node:assert"
|
|
196
|
-
* import { Number, Option } from "effect"
|
|
591
|
+
* Returns a function that divides its input by a specified divisor.
|
|
197
592
|
*
|
|
198
|
-
*
|
|
199
|
-
* assert.deepStrictEqual(Number.divide(6, 0), Option.none())
|
|
200
|
-
* ```
|
|
593
|
+
* @param divisor - The number to divide by
|
|
201
594
|
*
|
|
202
|
-
* @
|
|
203
|
-
*
|
|
595
|
+
* @returns A function that takes a dividend and returns the quotient wrapped
|
|
596
|
+
* in an Option (Option.none() if divisor is 0)
|
|
204
597
|
*/
|
|
205
|
-
(
|
|
598
|
+
(divisor: number): (dividend: number) => Option<number>
|
|
599
|
+
|
|
206
600
|
/**
|
|
207
|
-
*
|
|
601
|
+
* Divides the dividend by the divisor and returns the quotient wrapped in an
|
|
602
|
+
* Option.
|
|
208
603
|
*
|
|
209
|
-
* @
|
|
210
|
-
*
|
|
211
|
-
* import * as assert from "node:assert"
|
|
212
|
-
* import { Number, Option } from "effect"
|
|
604
|
+
* @param dividend - The number to be divided
|
|
605
|
+
* @param divisor - The number to divide by
|
|
213
606
|
*
|
|
214
|
-
*
|
|
215
|
-
* assert.deepStrictEqual(Number.divide(6, 0), Option.none())
|
|
216
|
-
* ```
|
|
217
|
-
*
|
|
218
|
-
* @category math
|
|
219
|
-
* @since 2.0.0
|
|
607
|
+
* @returns Some(quotient) if the divisor is not 0, None otherwise
|
|
220
608
|
*/
|
|
221
|
-
(
|
|
222
|
-
} = dual(
|
|
223
|
-
2,
|
|
224
|
-
(self: number, that: number): Option<number> => that === 0 ? option.none : option.some(self / that)
|
|
225
|
-
)
|
|
609
|
+
(dividend: number, divisor: number): Option<number>
|
|
610
|
+
} = dual(2, (dividend: number, divisor: number) => divisor === 0 ? option.none : option.some(dividend / divisor))
|
|
226
611
|
|
|
227
612
|
/**
|
|
228
|
-
*
|
|
613
|
+
* Performs division in the set of JavaScript numbers, but misbehaves for
|
|
614
|
+
* division by zero.
|
|
615
|
+
*
|
|
616
|
+
* Unlike {@link module:Number.divide} which returns an Option, this function
|
|
617
|
+
* directly returns a number or `Infinity` or `NaN`.
|
|
229
618
|
*
|
|
230
|
-
*
|
|
619
|
+
* - If the `divisor` is zero, it returns `Infinity`.
|
|
620
|
+
* - If both the `dividend` and the `divisor` are zero, then it returns `NaN`.
|
|
231
621
|
*
|
|
622
|
+
* @memberof Number
|
|
623
|
+
* @since 2.0.0
|
|
624
|
+
* @category math
|
|
232
625
|
* @example
|
|
233
|
-
* ```ts
|
|
234
|
-
* import * as assert from "node:assert"
|
|
235
|
-
* import { unsafeDivide } from "effect/Number"
|
|
236
626
|
*
|
|
237
|
-
*
|
|
627
|
+
* ```ts
|
|
628
|
+
* import * as assert from "node:assert/strict"
|
|
629
|
+
* import { pipe } from "effect"
|
|
630
|
+
* import * as Number from "effect/Number"
|
|
631
|
+
*
|
|
632
|
+
* // Data-first style (direct application)
|
|
633
|
+
* assert.equal(Number.unsafeDivide(6, 3), 2) // 6 ÷ 3 = 2
|
|
634
|
+
* assert.equal(Number.unsafeDivide(-8, 4), -2) // (-8) ÷ 4 = -2
|
|
635
|
+
* assert.equal(Number.unsafeDivide(-10, -5), 2) // (-10) ÷ (-5) = 2
|
|
636
|
+
* assert.equal(Number.unsafeDivide(1, 3), 0.3333333333333333)
|
|
637
|
+
*
|
|
638
|
+
* // Data-last style (pipeable)
|
|
639
|
+
* assert.equal(
|
|
640
|
+
* pipe(
|
|
641
|
+
* 10,
|
|
642
|
+
* Number.unsafeDivide(2) // 10 ÷ 2 = 5
|
|
643
|
+
* ),
|
|
644
|
+
* 5
|
|
645
|
+
* )
|
|
646
|
+
*
|
|
647
|
+
* // Chaining multiple divisions
|
|
648
|
+
* assert.equal(
|
|
649
|
+
* pipe(
|
|
650
|
+
* 24,
|
|
651
|
+
* Number.unsafeDivide(2), // 24 ÷ 2 = 12
|
|
652
|
+
* Number.unsafeDivide(3), // 12 ÷ 3 = 4
|
|
653
|
+
* Number.unsafeDivide(2) // 4 ÷ 2 = 2
|
|
654
|
+
* ),
|
|
655
|
+
* 2
|
|
656
|
+
* )
|
|
657
|
+
*
|
|
658
|
+
* assert.equal(Number.unsafeDivide(6, 0), Infinity)
|
|
659
|
+
*
|
|
660
|
+
* assert.equal(Number.unsafeDivide(0, 0), NaN)
|
|
661
|
+
*
|
|
662
|
+
* // Compare with safe division
|
|
663
|
+
* const safeResult = Number.divide(6, 3) // Option.some(2)
|
|
664
|
+
* const unsafeResult = Number.unsafeDivide(6, 3) // 2 directly
|
|
238
665
|
* ```
|
|
239
666
|
*
|
|
240
|
-
* @
|
|
241
|
-
* @
|
|
667
|
+
* @throws - An {@link module:Number.DivisionByZeroError} if the divisor is zero.
|
|
668
|
+
* @see {@link module:Number.divide} - Safe division returning an Option
|
|
242
669
|
*/
|
|
243
670
|
export const unsafeDivide: {
|
|
244
671
|
/**
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
* Throws a `RangeError` if the divisor is `0`.
|
|
248
|
-
*
|
|
249
|
-
* @example
|
|
250
|
-
* ```ts
|
|
251
|
-
* import * as assert from "node:assert"
|
|
252
|
-
* import { unsafeDivide } from "effect/Number"
|
|
672
|
+
* Returns a function that divides its input by a specified divisor.
|
|
253
673
|
*
|
|
254
|
-
*
|
|
255
|
-
* ```
|
|
674
|
+
* @param divisor - The number to divide by
|
|
256
675
|
*
|
|
257
|
-
* @
|
|
258
|
-
* @
|
|
676
|
+
* @returns A function that takes a dividend and returns the quotient
|
|
677
|
+
* @throws - An {@link module:Number.DivisionByZeroError} if the divisor is
|
|
678
|
+
* zero
|
|
259
679
|
*/
|
|
260
|
-
(
|
|
680
|
+
(divisor: number): (dividend: number) => number
|
|
681
|
+
|
|
261
682
|
/**
|
|
262
|
-
*
|
|
683
|
+
* Divides the dividend by the divisor and returns the quotient.
|
|
263
684
|
*
|
|
264
|
-
*
|
|
685
|
+
* If the divisor is zero, it returns Infinity.
|
|
265
686
|
*
|
|
266
|
-
* @
|
|
267
|
-
*
|
|
268
|
-
* import * as assert from "node:assert"
|
|
269
|
-
* import { unsafeDivide } from "effect/Number"
|
|
687
|
+
* @param dividend - The number to be divided
|
|
688
|
+
* @param divisor - The number to divide by
|
|
270
689
|
*
|
|
271
|
-
*
|
|
272
|
-
* ```
|
|
273
|
-
*
|
|
274
|
-
* @category math
|
|
275
|
-
* @since 2.0.0
|
|
690
|
+
* @returns The quotient of the division
|
|
276
691
|
*/
|
|
277
|
-
(
|
|
278
|
-
} = dual(2, (
|
|
692
|
+
(dividend: number, divisor: number): number
|
|
693
|
+
} = dual(2, (dividend: number, divisor: number): number => dividend / divisor)
|
|
279
694
|
|
|
280
695
|
/**
|
|
281
696
|
* Returns the result of adding `1` to a given number.
|
|
282
697
|
*
|
|
698
|
+
* @memberof Number
|
|
699
|
+
* @since 2.0.0
|
|
700
|
+
* @category math
|
|
283
701
|
* @example
|
|
702
|
+
*
|
|
284
703
|
* ```ts
|
|
285
|
-
* import * as assert from "node:assert"
|
|
704
|
+
* import * as assert from "node:assert/strict"
|
|
286
705
|
* import { increment } from "effect/Number"
|
|
287
706
|
*
|
|
288
|
-
* assert.
|
|
707
|
+
* assert.equal(increment(2), 3)
|
|
289
708
|
* ```
|
|
290
|
-
*
|
|
291
|
-
* @category math
|
|
292
|
-
* @since 2.0.0
|
|
293
709
|
*/
|
|
294
|
-
export const increment = (n: number): number => n
|
|
710
|
+
export const increment = (n: number): number => sum(n, 1)
|
|
295
711
|
|
|
296
712
|
/**
|
|
297
713
|
* Decrements a number by `1`.
|
|
298
714
|
*
|
|
715
|
+
* @memberof Number
|
|
716
|
+
* @since 2.0.0
|
|
717
|
+
* @category math
|
|
299
718
|
* @example
|
|
719
|
+
*
|
|
300
720
|
* ```ts
|
|
301
|
-
* import * as assert from "node:assert"
|
|
721
|
+
* import * as assert from "node:assert/strict"
|
|
302
722
|
* import { decrement } from "effect/Number"
|
|
303
723
|
*
|
|
304
|
-
* assert.
|
|
724
|
+
* assert.equal(decrement(3), 2)
|
|
305
725
|
* ```
|
|
306
|
-
*
|
|
307
|
-
* @category math
|
|
308
|
-
* @since 2.0.0
|
|
309
726
|
*/
|
|
310
|
-
export const decrement = (n: number): number => n
|
|
727
|
+
export const decrement = (n: number): number => subtract(n, 1)
|
|
311
728
|
|
|
312
729
|
/**
|
|
313
|
-
* @
|
|
730
|
+
* @memberof Number
|
|
314
731
|
* @since 2.0.0
|
|
732
|
+
* @category instances
|
|
315
733
|
*/
|
|
316
734
|
export const Equivalence: equivalence.Equivalence<number> = equivalence.number
|
|
317
735
|
|
|
318
736
|
/**
|
|
319
|
-
* @
|
|
737
|
+
* @memberof Number
|
|
320
738
|
* @since 2.0.0
|
|
739
|
+
* @category instances
|
|
321
740
|
*/
|
|
322
741
|
export const Order: order.Order<number> = order.number
|
|
323
742
|
|
|
324
743
|
/**
|
|
325
|
-
* Returns `true` if the first argument is less than the second, otherwise
|
|
744
|
+
* Returns `true` if the first argument is less than the second, otherwise
|
|
745
|
+
* `false`.
|
|
326
746
|
*
|
|
747
|
+
* @memberof Number
|
|
748
|
+
* @since 2.0.0
|
|
749
|
+
* @category predicates
|
|
327
750
|
* @example
|
|
751
|
+
*
|
|
328
752
|
* ```ts
|
|
329
|
-
* import * as assert from "node:assert"
|
|
753
|
+
* import * as assert from "node:assert/strict"
|
|
330
754
|
* import { lessThan } from "effect/Number"
|
|
331
755
|
*
|
|
332
|
-
* assert.
|
|
333
|
-
* assert.
|
|
334
|
-
* assert.
|
|
756
|
+
* assert.equal(lessThan(2, 3), true)
|
|
757
|
+
* assert.equal(lessThan(3, 3), false)
|
|
758
|
+
* assert.equal(lessThan(4, 3), false)
|
|
335
759
|
* ```
|
|
336
|
-
*
|
|
337
|
-
* @category predicates
|
|
338
|
-
* @since 2.0.0
|
|
339
760
|
*/
|
|
340
761
|
export const lessThan: {
|
|
341
762
|
/**
|
|
342
|
-
* Returns `true` if the first argument is less than the second, otherwise
|
|
763
|
+
* Returns `true` if the first argument is less than the second, otherwise
|
|
764
|
+
* `false`.
|
|
343
765
|
*
|
|
766
|
+
* @memberof Number
|
|
767
|
+
* @since 2.0.0
|
|
768
|
+
* @category predicates
|
|
344
769
|
* @example
|
|
770
|
+
*
|
|
345
771
|
* ```ts
|
|
346
|
-
* import * as assert from "node:assert"
|
|
772
|
+
* import * as assert from "node:assert/strict"
|
|
347
773
|
* import { lessThan } from "effect/Number"
|
|
348
774
|
*
|
|
349
|
-
* assert.
|
|
350
|
-
* assert.
|
|
351
|
-
* assert.
|
|
775
|
+
* assert.equal(lessThan(2, 3), true)
|
|
776
|
+
* assert.equal(lessThan(3, 3), false)
|
|
777
|
+
* assert.equal(lessThan(4, 3), false)
|
|
352
778
|
* ```
|
|
353
|
-
*
|
|
354
|
-
* @category predicates
|
|
355
|
-
* @since 2.0.0
|
|
356
779
|
*/
|
|
357
780
|
(that: number): (self: number) => boolean
|
|
358
781
|
/**
|
|
359
|
-
* Returns `true` if the first argument is less than the second, otherwise
|
|
782
|
+
* Returns `true` if the first argument is less than the second, otherwise
|
|
783
|
+
* `false`.
|
|
360
784
|
*
|
|
785
|
+
* @memberof Number
|
|
786
|
+
* @since 2.0.0
|
|
787
|
+
* @category predicates
|
|
361
788
|
* @example
|
|
789
|
+
*
|
|
362
790
|
* ```ts
|
|
363
|
-
* import * as assert from "node:assert"
|
|
791
|
+
* import * as assert from "node:assert/strict"
|
|
364
792
|
* import { lessThan } from "effect/Number"
|
|
365
793
|
*
|
|
366
|
-
* assert.
|
|
367
|
-
* assert.
|
|
368
|
-
* assert.
|
|
794
|
+
* assert.equal(lessThan(2, 3), true)
|
|
795
|
+
* assert.equal(lessThan(3, 3), false)
|
|
796
|
+
* assert.equal(lessThan(4, 3), false)
|
|
369
797
|
* ```
|
|
370
|
-
*
|
|
371
|
-
* @category predicates
|
|
372
|
-
* @since 2.0.0
|
|
373
798
|
*/
|
|
374
799
|
(self: number, that: number): boolean
|
|
375
800
|
} = order.lessThan(Order)
|
|
376
801
|
|
|
377
802
|
/**
|
|
378
|
-
* Returns a function that checks if a given `number` is less than or equal to
|
|
803
|
+
* Returns a function that checks if a given `number` is less than or equal to
|
|
804
|
+
* the provided one.
|
|
379
805
|
*
|
|
806
|
+
* @memberof Number
|
|
807
|
+
* @since 2.0.0
|
|
808
|
+
* @category predicates
|
|
380
809
|
* @example
|
|
810
|
+
*
|
|
381
811
|
* ```ts
|
|
382
|
-
* import * as assert from "node:assert"
|
|
812
|
+
* import * as assert from "node:assert/strict"
|
|
383
813
|
* import { lessThanOrEqualTo } from "effect/Number"
|
|
384
814
|
*
|
|
385
|
-
* assert.
|
|
386
|
-
* assert.
|
|
387
|
-
* assert.
|
|
815
|
+
* assert.equal(lessThanOrEqualTo(2, 3), true)
|
|
816
|
+
* assert.equal(lessThanOrEqualTo(3, 3), true)
|
|
817
|
+
* assert.equal(lessThanOrEqualTo(4, 3), false)
|
|
388
818
|
* ```
|
|
389
|
-
*
|
|
390
|
-
* @category predicates
|
|
391
|
-
* @since 2.0.0
|
|
392
819
|
*/
|
|
393
820
|
export const lessThanOrEqualTo: {
|
|
394
821
|
/**
|
|
395
|
-
* Returns a function that checks if a given `number` is less than or equal to
|
|
822
|
+
* Returns a function that checks if a given `number` is less than or equal to
|
|
823
|
+
* the provided one.
|
|
396
824
|
*
|
|
825
|
+
* @memberof Number
|
|
826
|
+
* @since 2.0.0
|
|
827
|
+
* @category predicates
|
|
397
828
|
* @example
|
|
829
|
+
*
|
|
398
830
|
* ```ts
|
|
399
|
-
* import * as assert from "node:assert"
|
|
831
|
+
* import * as assert from "node:assert/strict"
|
|
400
832
|
* import { lessThanOrEqualTo } from "effect/Number"
|
|
401
833
|
*
|
|
402
|
-
* assert.
|
|
403
|
-
* assert.
|
|
404
|
-
* assert.
|
|
834
|
+
* assert.equal(lessThanOrEqualTo(2, 3), true)
|
|
835
|
+
* assert.equal(lessThanOrEqualTo(3, 3), true)
|
|
836
|
+
* assert.equal(lessThanOrEqualTo(4, 3), false)
|
|
405
837
|
* ```
|
|
406
|
-
*
|
|
407
|
-
* @category predicates
|
|
408
|
-
* @since 2.0.0
|
|
409
838
|
*/
|
|
410
839
|
(that: number): (self: number) => boolean
|
|
411
840
|
/**
|
|
412
|
-
* Returns a function that checks if a given `number` is less than or equal to
|
|
841
|
+
* Returns a function that checks if a given `number` is less than or equal to
|
|
842
|
+
* the provided one.
|
|
413
843
|
*
|
|
844
|
+
* @memberof Number
|
|
845
|
+
* @since 2.0.0
|
|
846
|
+
* @category predicates
|
|
414
847
|
* @example
|
|
848
|
+
*
|
|
415
849
|
* ```ts
|
|
416
|
-
* import * as assert from "node:assert"
|
|
850
|
+
* import * as assert from "node:assert/strict"
|
|
417
851
|
* import { lessThanOrEqualTo } from "effect/Number"
|
|
418
852
|
*
|
|
419
|
-
* assert.
|
|
420
|
-
* assert.
|
|
421
|
-
* assert.
|
|
853
|
+
* assert.equal(lessThanOrEqualTo(2, 3), true)
|
|
854
|
+
* assert.equal(lessThanOrEqualTo(3, 3), true)
|
|
855
|
+
* assert.equal(lessThanOrEqualTo(4, 3), false)
|
|
422
856
|
* ```
|
|
423
|
-
*
|
|
424
|
-
* @category predicates
|
|
425
|
-
* @since 2.0.0
|
|
426
857
|
*/
|
|
427
858
|
(self: number, that: number): boolean
|
|
428
859
|
} = order.lessThanOrEqualTo(Order)
|
|
429
860
|
|
|
430
861
|
/**
|
|
431
|
-
* Returns `true` if the first argument is greater than the second, otherwise
|
|
862
|
+
* Returns `true` if the first argument is greater than the second, otherwise
|
|
863
|
+
* `false`.
|
|
432
864
|
*
|
|
865
|
+
* @memberof Number
|
|
866
|
+
* @since 2.0.0
|
|
867
|
+
* @category predicates
|
|
433
868
|
* @example
|
|
869
|
+
*
|
|
434
870
|
* ```ts
|
|
435
|
-
* import * as assert from "node:assert"
|
|
871
|
+
* import * as assert from "node:assert/strict"
|
|
436
872
|
* import { greaterThan } from "effect/Number"
|
|
437
873
|
*
|
|
438
|
-
* assert.
|
|
439
|
-
* assert.
|
|
440
|
-
* assert.
|
|
874
|
+
* assert.equal(greaterThan(2, 3), false)
|
|
875
|
+
* assert.equal(greaterThan(3, 3), false)
|
|
876
|
+
* assert.equal(greaterThan(4, 3), true)
|
|
441
877
|
* ```
|
|
442
|
-
*
|
|
443
|
-
* @category predicates
|
|
444
|
-
* @since 2.0.0
|
|
445
878
|
*/
|
|
446
879
|
export const greaterThan: {
|
|
447
880
|
/**
|
|
448
|
-
* Returns `true` if the first argument is greater than the second, otherwise
|
|
881
|
+
* Returns `true` if the first argument is greater than the second, otherwise
|
|
882
|
+
* `false`.
|
|
449
883
|
*
|
|
884
|
+
* @memberof Number
|
|
885
|
+
* @since 2.0.0
|
|
886
|
+
* @category predicates
|
|
450
887
|
* @example
|
|
888
|
+
*
|
|
451
889
|
* ```ts
|
|
452
|
-
* import * as assert from "node:assert"
|
|
890
|
+
* import * as assert from "node:assert/strict"
|
|
453
891
|
* import { greaterThan } from "effect/Number"
|
|
454
892
|
*
|
|
455
|
-
* assert.
|
|
456
|
-
* assert.
|
|
457
|
-
* assert.
|
|
893
|
+
* assert.equal(greaterThan(2, 3), false)
|
|
894
|
+
* assert.equal(greaterThan(3, 3), false)
|
|
895
|
+
* assert.equal(greaterThan(4, 3), true)
|
|
458
896
|
* ```
|
|
459
|
-
*
|
|
460
|
-
* @category predicates
|
|
461
|
-
* @since 2.0.0
|
|
462
897
|
*/
|
|
463
898
|
(that: number): (self: number) => boolean
|
|
464
899
|
/**
|
|
465
|
-
* Returns `true` if the first argument is greater than the second, otherwise
|
|
900
|
+
* Returns `true` if the first argument is greater than the second, otherwise
|
|
901
|
+
* `false`.
|
|
466
902
|
*
|
|
903
|
+
* @memberof Number
|
|
904
|
+
* @since 2.0.0
|
|
905
|
+
* @category predicates
|
|
467
906
|
* @example
|
|
907
|
+
*
|
|
468
908
|
* ```ts
|
|
469
|
-
* import * as assert from "node:assert"
|
|
909
|
+
* import * as assert from "node:assert/strict"
|
|
470
910
|
* import { greaterThan } from "effect/Number"
|
|
471
911
|
*
|
|
472
|
-
* assert.
|
|
473
|
-
* assert.
|
|
474
|
-
* assert.
|
|
912
|
+
* assert.equal(greaterThan(2, 3), false)
|
|
913
|
+
* assert.equal(greaterThan(3, 3), false)
|
|
914
|
+
* assert.equal(greaterThan(4, 3), true)
|
|
475
915
|
* ```
|
|
476
|
-
*
|
|
477
|
-
* @category predicates
|
|
478
|
-
* @since 2.0.0
|
|
479
916
|
*/
|
|
480
917
|
(self: number, that: number): boolean
|
|
481
918
|
} = order.greaterThan(Order)
|
|
482
919
|
|
|
483
920
|
/**
|
|
484
|
-
* Returns a function that checks if a given `number` is greater than or equal
|
|
921
|
+
* Returns a function that checks if a given `number` is greater than or equal
|
|
922
|
+
* to the provided one.
|
|
485
923
|
*
|
|
924
|
+
* @memberof Number
|
|
925
|
+
* @since 2.0.0
|
|
926
|
+
* @category predicates
|
|
486
927
|
* @example
|
|
928
|
+
*
|
|
487
929
|
* ```ts
|
|
488
|
-
* import * as assert from "node:assert"
|
|
930
|
+
* import * as assert from "node:assert/strict"
|
|
489
931
|
* import { greaterThanOrEqualTo } from "effect/Number"
|
|
490
932
|
*
|
|
491
|
-
* assert.
|
|
492
|
-
* assert.
|
|
493
|
-
* assert.
|
|
933
|
+
* assert.equal(greaterThanOrEqualTo(2, 3), false)
|
|
934
|
+
* assert.equal(greaterThanOrEqualTo(3, 3), true)
|
|
935
|
+
* assert.equal(greaterThanOrEqualTo(4, 3), true)
|
|
494
936
|
* ```
|
|
495
|
-
*
|
|
496
|
-
* @category predicates
|
|
497
|
-
* @since 2.0.0
|
|
498
937
|
*/
|
|
499
938
|
export const greaterThanOrEqualTo: {
|
|
500
939
|
/**
|
|
501
|
-
* Returns a function that checks if a given `number` is greater than or equal
|
|
940
|
+
* Returns a function that checks if a given `number` is greater than or equal
|
|
941
|
+
* to the provided one.
|
|
502
942
|
*
|
|
943
|
+
* @memberof Number
|
|
944
|
+
* @since 2.0.0
|
|
945
|
+
* @category predicates
|
|
503
946
|
* @example
|
|
947
|
+
*
|
|
504
948
|
* ```ts
|
|
505
|
-
* import * as assert from "node:assert"
|
|
949
|
+
* import * as assert from "node:assert/strict"
|
|
506
950
|
* import { greaterThanOrEqualTo } from "effect/Number"
|
|
507
951
|
*
|
|
508
|
-
* assert.
|
|
509
|
-
* assert.
|
|
510
|
-
* assert.
|
|
952
|
+
* assert.equal(greaterThanOrEqualTo(2, 3), false)
|
|
953
|
+
* assert.equal(greaterThanOrEqualTo(3, 3), true)
|
|
954
|
+
* assert.equal(greaterThanOrEqualTo(4, 3), true)
|
|
511
955
|
* ```
|
|
512
|
-
*
|
|
513
|
-
* @category predicates
|
|
514
|
-
* @since 2.0.0
|
|
515
956
|
*/
|
|
516
957
|
(that: number): (self: number) => boolean
|
|
517
958
|
/**
|
|
518
|
-
* Returns a function that checks if a given `number` is greater than or equal
|
|
959
|
+
* Returns a function that checks if a given `number` is greater than or equal
|
|
960
|
+
* to the provided one.
|
|
519
961
|
*
|
|
962
|
+
* @memberof Number
|
|
963
|
+
* @since 2.0.0
|
|
964
|
+
* @category predicates
|
|
520
965
|
* @example
|
|
966
|
+
*
|
|
521
967
|
* ```ts
|
|
522
|
-
* import * as assert from "node:assert"
|
|
968
|
+
* import * as assert from "node:assert/strict"
|
|
523
969
|
* import { greaterThanOrEqualTo } from "effect/Number"
|
|
524
970
|
*
|
|
525
|
-
* assert.
|
|
526
|
-
* assert.
|
|
527
|
-
* assert.
|
|
971
|
+
* assert.equal(greaterThanOrEqualTo(2, 3), false)
|
|
972
|
+
* assert.equal(greaterThanOrEqualTo(3, 3), true)
|
|
973
|
+
* assert.equal(greaterThanOrEqualTo(4, 3), true)
|
|
528
974
|
* ```
|
|
529
|
-
*
|
|
530
|
-
* @category predicates
|
|
531
|
-
* @since 2.0.0
|
|
532
975
|
*/
|
|
533
976
|
(self: number, that: number): boolean
|
|
534
977
|
} = order.greaterThanOrEqualTo(Order)
|
|
@@ -536,83 +979,87 @@ export const greaterThanOrEqualTo: {
|
|
|
536
979
|
/**
|
|
537
980
|
* Checks if a `number` is between a `minimum` and `maximum` value (inclusive).
|
|
538
981
|
*
|
|
982
|
+
* @memberof Number
|
|
983
|
+
* @since 2.0.0
|
|
984
|
+
* @category predicates
|
|
539
985
|
* @example
|
|
986
|
+
*
|
|
540
987
|
* ```ts
|
|
541
|
-
* import * as assert from "node:assert"
|
|
988
|
+
* import * as assert from "node:assert/strict"
|
|
542
989
|
* import { Number } from "effect"
|
|
543
990
|
*
|
|
544
991
|
* const between = Number.between({ minimum: 0, maximum: 5 })
|
|
545
992
|
*
|
|
546
|
-
* assert.
|
|
547
|
-
* assert.
|
|
548
|
-
* assert.
|
|
993
|
+
* assert.equal(between(3), true)
|
|
994
|
+
* assert.equal(between(-1), false)
|
|
995
|
+
* assert.equal(between(6), false)
|
|
549
996
|
* ```
|
|
550
|
-
*
|
|
551
|
-
* @category predicates
|
|
552
|
-
* @since 2.0.0
|
|
553
997
|
*/
|
|
554
998
|
export const between: {
|
|
555
999
|
/**
|
|
556
1000
|
* Checks if a `number` is between a `minimum` and `maximum` value (inclusive).
|
|
557
1001
|
*
|
|
1002
|
+
* @memberof Number
|
|
1003
|
+
* @since 2.0.0
|
|
1004
|
+
* @category predicates
|
|
558
1005
|
* @example
|
|
1006
|
+
*
|
|
559
1007
|
* ```ts
|
|
560
|
-
* import * as assert from "node:assert"
|
|
1008
|
+
* import * as assert from "node:assert/strict"
|
|
561
1009
|
* import { Number } from "effect"
|
|
562
1010
|
*
|
|
563
1011
|
* const between = Number.between({ minimum: 0, maximum: 5 })
|
|
564
1012
|
*
|
|
565
|
-
* assert.
|
|
566
|
-
* assert.
|
|
567
|
-
* assert.
|
|
1013
|
+
* assert.equal(between(3), true)
|
|
1014
|
+
* assert.equal(between(-1), false)
|
|
1015
|
+
* assert.equal(between(6), false)
|
|
568
1016
|
* ```
|
|
569
|
-
*
|
|
570
|
-
* @category predicates
|
|
571
|
-
* @since 2.0.0
|
|
572
1017
|
*/
|
|
573
|
-
(
|
|
574
|
-
options: {
|
|
575
|
-
minimum: number
|
|
576
|
-
maximum: number
|
|
577
|
-
}
|
|
578
|
-
): (self: number) => boolean
|
|
1018
|
+
(options: { minimum: number; maximum: number }): (self: number) => boolean
|
|
579
1019
|
/**
|
|
580
1020
|
* Checks if a `number` is between a `minimum` and `maximum` value (inclusive).
|
|
581
1021
|
*
|
|
1022
|
+
* @memberof Number
|
|
1023
|
+
* @since 2.0.0
|
|
1024
|
+
* @category predicates
|
|
582
1025
|
* @example
|
|
1026
|
+
*
|
|
583
1027
|
* ```ts
|
|
584
|
-
* import * as assert from "node:assert"
|
|
1028
|
+
* import * as assert from "node:assert/strict"
|
|
585
1029
|
* import { Number } from "effect"
|
|
586
1030
|
*
|
|
587
1031
|
* const between = Number.between({ minimum: 0, maximum: 5 })
|
|
588
1032
|
*
|
|
589
|
-
* assert.
|
|
590
|
-
* assert.
|
|
591
|
-
* assert.
|
|
1033
|
+
* assert.equal(between(3), true)
|
|
1034
|
+
* assert.equal(between(-1), false)
|
|
1035
|
+
* assert.equal(between(6), false)
|
|
592
1036
|
* ```
|
|
593
|
-
*
|
|
594
|
-
* @category predicates
|
|
595
|
-
* @since 2.0.0
|
|
596
1037
|
*/
|
|
597
1038
|
(
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
1039
|
+
self: number,
|
|
1040
|
+
options: {
|
|
1041
|
+
minimum: number
|
|
1042
|
+
maximum: number
|
|
1043
|
+
}
|
|
603
1044
|
): boolean
|
|
604
1045
|
} = order.between(Order)
|
|
605
1046
|
|
|
606
1047
|
/**
|
|
607
|
-
* Restricts the given `number` to be within the range specified by the
|
|
1048
|
+
* Restricts the given `number` to be within the range specified by the
|
|
1049
|
+
* `minimum` and `maximum` values.
|
|
608
1050
|
*
|
|
609
|
-
* - If the `number` is less than the `minimum` value, the function returns the
|
|
610
|
-
*
|
|
1051
|
+
* - If the `number` is less than the `minimum` value, the function returns the
|
|
1052
|
+
* `minimum` value.
|
|
1053
|
+
* - If the `number` is greater than the `maximum` value, the function returns the
|
|
1054
|
+
* `maximum` value.
|
|
611
1055
|
* - Otherwise, it returns the original `number`.
|
|
612
1056
|
*
|
|
1057
|
+
* @memberof Number
|
|
1058
|
+
* @since 2.0.0
|
|
613
1059
|
* @example
|
|
1060
|
+
*
|
|
614
1061
|
* ```ts
|
|
615
|
-
* import * as assert from "node:assert"
|
|
1062
|
+
* import * as assert from "node:assert/strict"
|
|
616
1063
|
* import { Number } from "effect"
|
|
617
1064
|
*
|
|
618
1065
|
* const clamp = Number.clamp({ minimum: 1, maximum: 5 })
|
|
@@ -621,20 +1068,24 @@ export const between: {
|
|
|
621
1068
|
* assert.equal(clamp(0), 1)
|
|
622
1069
|
* assert.equal(clamp(6), 5)
|
|
623
1070
|
* ```
|
|
624
|
-
*
|
|
625
|
-
* @since 2.0.0
|
|
626
1071
|
*/
|
|
627
1072
|
export const clamp: {
|
|
628
1073
|
/**
|
|
629
|
-
* Restricts the given `number` to be within the range specified by the
|
|
1074
|
+
* Restricts the given `number` to be within the range specified by the
|
|
1075
|
+
* `minimum` and `maximum` values.
|
|
630
1076
|
*
|
|
631
|
-
* - If the `number` is less than the `minimum` value, the function returns the
|
|
632
|
-
*
|
|
1077
|
+
* - If the `number` is less than the `minimum` value, the function returns the
|
|
1078
|
+
* `minimum` value.
|
|
1079
|
+
* - If the `number` is greater than the `maximum` value, the function returns the
|
|
1080
|
+
* `maximum` value.
|
|
633
1081
|
* - Otherwise, it returns the original `number`.
|
|
634
1082
|
*
|
|
1083
|
+
* @memberof Number
|
|
1084
|
+
* @since 2.0.0
|
|
635
1085
|
* @example
|
|
1086
|
+
*
|
|
636
1087
|
* ```ts
|
|
637
|
-
* import * as assert from "node:assert"
|
|
1088
|
+
* import * as assert from "node:assert/strict"
|
|
638
1089
|
* import { Number } from "effect"
|
|
639
1090
|
*
|
|
640
1091
|
* const clamp = Number.clamp({ minimum: 1, maximum: 5 })
|
|
@@ -643,25 +1094,24 @@ export const clamp: {
|
|
|
643
1094
|
* assert.equal(clamp(0), 1)
|
|
644
1095
|
* assert.equal(clamp(6), 5)
|
|
645
1096
|
* ```
|
|
646
|
-
*
|
|
647
|
-
* @since 2.0.0
|
|
648
1097
|
*/
|
|
649
|
-
(
|
|
650
|
-
options: {
|
|
651
|
-
minimum: number
|
|
652
|
-
maximum: number
|
|
653
|
-
}
|
|
654
|
-
): (self: number) => number
|
|
1098
|
+
(options: { minimum: number; maximum: number }): (self: number) => number
|
|
655
1099
|
/**
|
|
656
|
-
* Restricts the given `number` to be within the range specified by the
|
|
1100
|
+
* Restricts the given `number` to be within the range specified by the
|
|
1101
|
+
* `minimum` and `maximum` values.
|
|
657
1102
|
*
|
|
658
|
-
* - If the `number` is less than the `minimum` value, the function returns the
|
|
659
|
-
*
|
|
1103
|
+
* - If the `number` is less than the `minimum` value, the function returns the
|
|
1104
|
+
* `minimum` value.
|
|
1105
|
+
* - If the `number` is greater than the `maximum` value, the function returns the
|
|
1106
|
+
* `maximum` value.
|
|
660
1107
|
* - Otherwise, it returns the original `number`.
|
|
661
1108
|
*
|
|
1109
|
+
* @memberof Number
|
|
1110
|
+
* @since 2.0.0
|
|
662
1111
|
* @example
|
|
1112
|
+
*
|
|
663
1113
|
* ```ts
|
|
664
|
-
* import * as assert from "node:assert"
|
|
1114
|
+
* import * as assert from "node:assert/strict"
|
|
665
1115
|
* import { Number } from "effect"
|
|
666
1116
|
*
|
|
667
1117
|
* const clamp = Number.clamp({ minimum: 1, maximum: 5 })
|
|
@@ -670,58 +1120,59 @@ export const clamp: {
|
|
|
670
1120
|
* assert.equal(clamp(0), 1)
|
|
671
1121
|
* assert.equal(clamp(6), 5)
|
|
672
1122
|
* ```
|
|
673
|
-
*
|
|
674
|
-
* @since 2.0.0
|
|
675
1123
|
*/
|
|
676
1124
|
(
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1125
|
+
self: number,
|
|
1126
|
+
options: {
|
|
1127
|
+
minimum: number
|
|
1128
|
+
maximum: number
|
|
1129
|
+
}
|
|
682
1130
|
): number
|
|
683
1131
|
} = order.clamp(Order)
|
|
684
1132
|
|
|
685
1133
|
/**
|
|
686
1134
|
* Returns the minimum between two `number`s.
|
|
687
1135
|
*
|
|
1136
|
+
* @memberof Number
|
|
1137
|
+
* @since 2.0.0
|
|
688
1138
|
* @example
|
|
1139
|
+
*
|
|
689
1140
|
* ```ts
|
|
690
|
-
* import * as assert from "node:assert"
|
|
1141
|
+
* import * as assert from "node:assert/strict"
|
|
691
1142
|
* import { min } from "effect/Number"
|
|
692
1143
|
*
|
|
693
|
-
* assert.
|
|
1144
|
+
* assert.equal(min(2, 3), 2)
|
|
694
1145
|
* ```
|
|
695
|
-
*
|
|
696
|
-
* @since 2.0.0
|
|
697
1146
|
*/
|
|
698
1147
|
export const min: {
|
|
699
1148
|
/**
|
|
700
1149
|
* Returns the minimum between two `number`s.
|
|
701
1150
|
*
|
|
1151
|
+
* @memberof Number
|
|
1152
|
+
* @since 2.0.0
|
|
702
1153
|
* @example
|
|
1154
|
+
*
|
|
703
1155
|
* ```ts
|
|
704
|
-
* import * as assert from "node:assert"
|
|
1156
|
+
* import * as assert from "node:assert/strict"
|
|
705
1157
|
* import { min } from "effect/Number"
|
|
706
1158
|
*
|
|
707
|
-
* assert.
|
|
1159
|
+
* assert.equal(min(2, 3), 2)
|
|
708
1160
|
* ```
|
|
709
|
-
*
|
|
710
|
-
* @since 2.0.0
|
|
711
1161
|
*/
|
|
712
1162
|
(that: number): (self: number) => number
|
|
713
1163
|
/**
|
|
714
1164
|
* Returns the minimum between two `number`s.
|
|
715
1165
|
*
|
|
1166
|
+
* @memberof Number
|
|
1167
|
+
* @since 2.0.0
|
|
716
1168
|
* @example
|
|
1169
|
+
*
|
|
717
1170
|
* ```ts
|
|
718
|
-
* import * as assert from "node:assert"
|
|
1171
|
+
* import * as assert from "node:assert/strict"
|
|
719
1172
|
* import { min } from "effect/Number"
|
|
720
1173
|
*
|
|
721
|
-
* assert.
|
|
1174
|
+
* assert.equal(min(2, 3), 2)
|
|
722
1175
|
* ```
|
|
723
|
-
*
|
|
724
|
-
* @since 2.0.0
|
|
725
1176
|
*/
|
|
726
1177
|
(self: number, that: number): number
|
|
727
1178
|
} = order.min(Order)
|
|
@@ -729,43 +1180,46 @@ export const min: {
|
|
|
729
1180
|
/**
|
|
730
1181
|
* Returns the maximum between two `number`s.
|
|
731
1182
|
*
|
|
1183
|
+
* @memberof Number
|
|
1184
|
+
* @since 2.0.0
|
|
732
1185
|
* @example
|
|
1186
|
+
*
|
|
733
1187
|
* ```ts
|
|
734
|
-
* import * as assert from "node:assert"
|
|
1188
|
+
* import * as assert from "node:assert/strict"
|
|
735
1189
|
* import { max } from "effect/Number"
|
|
736
1190
|
*
|
|
737
|
-
* assert.
|
|
1191
|
+
* assert.equal(max(2, 3), 3)
|
|
738
1192
|
* ```
|
|
739
|
-
*
|
|
740
|
-
* @since 2.0.0
|
|
741
1193
|
*/
|
|
742
1194
|
export const max: {
|
|
743
1195
|
/**
|
|
744
1196
|
* Returns the maximum between two `number`s.
|
|
745
1197
|
*
|
|
1198
|
+
* @memberof Number
|
|
1199
|
+
* @since 2.0.0
|
|
746
1200
|
* @example
|
|
1201
|
+
*
|
|
747
1202
|
* ```ts
|
|
748
|
-
* import * as assert from "node:assert"
|
|
1203
|
+
* import * as assert from "node:assert/strict"
|
|
749
1204
|
* import { max } from "effect/Number"
|
|
750
1205
|
*
|
|
751
|
-
* assert.
|
|
1206
|
+
* assert.equal(max(2, 3), 3)
|
|
752
1207
|
* ```
|
|
753
|
-
*
|
|
754
|
-
* @since 2.0.0
|
|
755
1208
|
*/
|
|
756
1209
|
(that: number): (self: number) => number
|
|
757
1210
|
/**
|
|
758
1211
|
* Returns the maximum between two `number`s.
|
|
759
1212
|
*
|
|
1213
|
+
* @memberof Number
|
|
1214
|
+
* @since 2.0.0
|
|
760
1215
|
* @example
|
|
1216
|
+
*
|
|
761
1217
|
* ```ts
|
|
762
|
-
* import * as assert from "node:assert"
|
|
1218
|
+
* import * as assert from "node:assert/strict"
|
|
763
1219
|
* import { max } from "effect/Number"
|
|
764
1220
|
*
|
|
765
|
-
* assert.
|
|
1221
|
+
* assert.equal(max(2, 3), 3)
|
|
766
1222
|
* ```
|
|
767
|
-
*
|
|
768
|
-
* @since 2.0.0
|
|
769
1223
|
*/
|
|
770
1224
|
(self: number, that: number): number
|
|
771
1225
|
} = order.max(Order)
|
|
@@ -773,149 +1227,119 @@ export const max: {
|
|
|
773
1227
|
/**
|
|
774
1228
|
* Determines the sign of a given `number`.
|
|
775
1229
|
*
|
|
1230
|
+
* @memberof Number
|
|
1231
|
+
* @since 2.0.0
|
|
1232
|
+
* @category math
|
|
776
1233
|
* @example
|
|
1234
|
+
*
|
|
777
1235
|
* ```ts
|
|
778
|
-
* import * as assert from "node:assert"
|
|
1236
|
+
* import * as assert from "node:assert/strict"
|
|
779
1237
|
* import { sign } from "effect/Number"
|
|
780
1238
|
*
|
|
781
|
-
* assert.
|
|
782
|
-
* assert.
|
|
783
|
-
* assert.
|
|
1239
|
+
* assert.equal(sign(-5), -1)
|
|
1240
|
+
* assert.equal(sign(0), 0)
|
|
1241
|
+
* assert.equal(sign(5), 1)
|
|
784
1242
|
* ```
|
|
785
|
-
*
|
|
786
|
-
* @category math
|
|
787
|
-
* @since 2.0.0
|
|
788
1243
|
*/
|
|
789
1244
|
export const sign = (n: number): Ordering => Order(n, 0)
|
|
790
1245
|
|
|
791
1246
|
/**
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
* @example
|
|
795
|
-
* ```ts
|
|
796
|
-
* import * as assert from "node:assert"
|
|
797
|
-
* import { sumAll } from "effect/Number"
|
|
1247
|
+
* Returns the remainder left over when one operand is divided by a second
|
|
1248
|
+
* operand.
|
|
798
1249
|
*
|
|
799
|
-
*
|
|
800
|
-
* ```
|
|
1250
|
+
* It always takes the sign of the dividend.
|
|
801
1251
|
*
|
|
802
|
-
* @
|
|
1252
|
+
* @memberof Number
|
|
803
1253
|
* @since 2.0.0
|
|
804
|
-
*/
|
|
805
|
-
export const sumAll = (collection: Iterable<number>): number => {
|
|
806
|
-
let out = 0
|
|
807
|
-
for (const n of collection) {
|
|
808
|
-
out += n
|
|
809
|
-
}
|
|
810
|
-
return out
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
/**
|
|
814
|
-
* Takes an `Iterable` of `number`s and returns their multiplication as a single `number`.
|
|
815
|
-
*
|
|
816
|
-
* @example
|
|
817
|
-
* ```ts
|
|
818
|
-
* import * as assert from "node:assert"
|
|
819
|
-
* import { multiplyAll } from "effect/Number"
|
|
820
|
-
*
|
|
821
|
-
* assert.deepStrictEqual(multiplyAll([2, 3, 4]), 24)
|
|
822
|
-
* ```
|
|
823
|
-
*
|
|
824
1254
|
* @category math
|
|
825
|
-
* @since 2.0.0
|
|
826
|
-
*/
|
|
827
|
-
export const multiplyAll = (collection: Iterable<number>): number => {
|
|
828
|
-
let out = 1
|
|
829
|
-
for (const n of collection) {
|
|
830
|
-
if (n === 0) {
|
|
831
|
-
return 0
|
|
832
|
-
}
|
|
833
|
-
out *= n
|
|
834
|
-
}
|
|
835
|
-
return out
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
/**
|
|
839
|
-
* Returns the remainder left over when one operand is divided by a second operand.
|
|
840
|
-
*
|
|
841
|
-
* It always takes the sign of the dividend.
|
|
842
|
-
*
|
|
843
1255
|
* @example
|
|
1256
|
+
*
|
|
844
1257
|
* ```ts
|
|
845
|
-
* import * as assert from "node:assert"
|
|
1258
|
+
* import * as assert from "node:assert/strict"
|
|
846
1259
|
* import { remainder } from "effect/Number"
|
|
847
1260
|
*
|
|
848
|
-
* assert.
|
|
849
|
-
* assert.
|
|
850
|
-
* assert.
|
|
1261
|
+
* assert.equal(remainder(2, 2), 0)
|
|
1262
|
+
* assert.equal(remainder(3, 2), 1)
|
|
1263
|
+
* assert.equal(remainder(-4, 2), -0)
|
|
851
1264
|
* ```
|
|
852
|
-
*
|
|
853
|
-
* @category math
|
|
854
|
-
* @since 2.0.0
|
|
855
1265
|
*/
|
|
856
1266
|
export const remainder: {
|
|
857
1267
|
/**
|
|
858
|
-
* Returns the remainder left over when one operand is divided by a second
|
|
1268
|
+
* Returns the remainder left over when one operand is divided by a second
|
|
1269
|
+
* operand.
|
|
859
1270
|
*
|
|
860
1271
|
* It always takes the sign of the dividend.
|
|
861
1272
|
*
|
|
1273
|
+
* @memberof Number
|
|
1274
|
+
* @since 2.0.0
|
|
1275
|
+
* @category math
|
|
862
1276
|
* @example
|
|
1277
|
+
*
|
|
863
1278
|
* ```ts
|
|
864
|
-
* import * as assert from "node:assert"
|
|
1279
|
+
* import * as assert from "node:assert/strict"
|
|
865
1280
|
* import { remainder } from "effect/Number"
|
|
866
1281
|
*
|
|
867
|
-
* assert.
|
|
868
|
-
* assert.
|
|
869
|
-
* assert.
|
|
1282
|
+
* assert.equal(remainder(2, 2), 0)
|
|
1283
|
+
* assert.equal(remainder(3, 2), 1)
|
|
1284
|
+
* assert.equal(remainder(-4, 2), -0)
|
|
870
1285
|
* ```
|
|
871
|
-
*
|
|
872
|
-
* @category math
|
|
873
|
-
* @since 2.0.0
|
|
874
1286
|
*/
|
|
875
|
-
(divisor: number): (
|
|
1287
|
+
(divisor: number): (dividend: number) => number
|
|
876
1288
|
/**
|
|
877
|
-
* Returns the remainder left over when one operand is divided by a second
|
|
1289
|
+
* Returns the remainder left over when one operand is divided by a second
|
|
1290
|
+
* operand.
|
|
878
1291
|
*
|
|
879
1292
|
* It always takes the sign of the dividend.
|
|
880
1293
|
*
|
|
1294
|
+
* @memberof Number
|
|
1295
|
+
* @since 2.0.0
|
|
1296
|
+
* @category math
|
|
881
1297
|
* @example
|
|
1298
|
+
*
|
|
882
1299
|
* ```ts
|
|
883
|
-
* import * as assert from "node:assert"
|
|
1300
|
+
* import * as assert from "node:assert/strict"
|
|
884
1301
|
* import { remainder } from "effect/Number"
|
|
885
1302
|
*
|
|
886
|
-
* assert.
|
|
887
|
-
* assert.
|
|
888
|
-
* assert.
|
|
1303
|
+
* assert.equal(remainder(2, 2), 0)
|
|
1304
|
+
* assert.equal(remainder(3, 2), 1)
|
|
1305
|
+
* assert.equal(remainder(-4, 2), -0)
|
|
889
1306
|
* ```
|
|
890
|
-
*
|
|
891
|
-
* @category math
|
|
892
|
-
* @since 2.0.0
|
|
893
1307
|
*/
|
|
894
|
-
(
|
|
895
|
-
} = dual(2, (
|
|
1308
|
+
(dividend: number, divisor: number): number
|
|
1309
|
+
} = dual(2, (dividend: number, divisor: number): number => {
|
|
896
1310
|
// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034
|
|
897
|
-
const selfDecCount = (
|
|
1311
|
+
const selfDecCount = (dividend.toString().split(".")[1] || "").length
|
|
898
1312
|
const divisorDecCount = (divisor.toString().split(".")[1] || "").length
|
|
899
1313
|
const decCount = selfDecCount > divisorDecCount ? selfDecCount : divisorDecCount
|
|
900
|
-
const selfInt = parseInt(
|
|
1314
|
+
const selfInt = parseInt(dividend.toFixed(decCount).replace(".", ""))
|
|
901
1315
|
const divisorInt = parseInt(divisor.toFixed(decCount).replace(".", ""))
|
|
902
1316
|
return (selfInt % divisorInt) / Math.pow(10, decCount)
|
|
903
1317
|
})
|
|
904
1318
|
|
|
905
1319
|
/**
|
|
906
|
-
* Returns the next power of 2
|
|
1320
|
+
* Returns the next power of 2 greater than or equal to the given number.
|
|
1321
|
+
*
|
|
1322
|
+
* - For `positive` inputs, returns the smallest power of 2 that is >= the input
|
|
1323
|
+
* - For `zero`, returns 2
|
|
1324
|
+
* - For `negative` inputs, returns NaN (as logarithms of negative numbers are
|
|
1325
|
+
* undefined)
|
|
1326
|
+
* - For `NaN` input, returns NaN
|
|
1327
|
+
* - For `Infinity`, returns Infinity
|
|
907
1328
|
*
|
|
1329
|
+
* @memberof Number
|
|
1330
|
+
* @since 2.0.0
|
|
1331
|
+
* @category math
|
|
908
1332
|
* @example
|
|
1333
|
+
*
|
|
909
1334
|
* ```ts
|
|
910
|
-
* import * as assert from "node:assert"
|
|
1335
|
+
* import * as assert from "node:assert/strict"
|
|
911
1336
|
* import { nextPow2 } from "effect/Number"
|
|
912
1337
|
*
|
|
913
|
-
* assert.
|
|
914
|
-
* assert.
|
|
1338
|
+
* assert.equal(nextPow2(5), 8)
|
|
1339
|
+
* assert.equal(nextPow2(17), 32)
|
|
1340
|
+
* assert.equal(nextPow2(0), 2)
|
|
1341
|
+
* assert.equal(Number.isNaN(nextPow2(-1)), true) // Negative inputs result in NaN
|
|
915
1342
|
* ```
|
|
916
|
-
*
|
|
917
|
-
* @category math
|
|
918
|
-
* @since 2.0.0
|
|
919
1343
|
*/
|
|
920
1344
|
export const nextPow2 = (n: number): number => {
|
|
921
1345
|
const nextPow = Math.ceil(Math.log(n) / Math.log(2))
|
|
@@ -923,13 +1347,26 @@ export const nextPow2 = (n: number): number => {
|
|
|
923
1347
|
}
|
|
924
1348
|
|
|
925
1349
|
/**
|
|
926
|
-
* Tries to parse a `number` from a `string` using the `Number()` function.
|
|
927
|
-
*
|
|
1350
|
+
* Tries to parse a `number` from a `string` using the `Number()` function. The
|
|
1351
|
+
* following special string values are supported: "NaN", "Infinity",
|
|
1352
|
+
* "-Infinity".
|
|
928
1353
|
*
|
|
929
|
-
* @
|
|
1354
|
+
* @memberof Number
|
|
930
1355
|
* @since 2.0.0
|
|
1356
|
+
* @category constructors
|
|
931
1357
|
*/
|
|
932
|
-
export const parse
|
|
1358
|
+
export const parse: {
|
|
1359
|
+
/**
|
|
1360
|
+
* Tries to parse a `number` from a `string` using the `Number()` function. The
|
|
1361
|
+
* following special string values are supported: "NaN", "Infinity",
|
|
1362
|
+
* "-Infinity".
|
|
1363
|
+
*
|
|
1364
|
+
* @memberof Number
|
|
1365
|
+
* @since 2.0.0
|
|
1366
|
+
* @category constructors
|
|
1367
|
+
*/
|
|
1368
|
+
(s: string): Option<number>
|
|
1369
|
+
} = (s) => {
|
|
933
1370
|
if (s === "NaN") {
|
|
934
1371
|
return option.some(NaN)
|
|
935
1372
|
}
|
|
@@ -943,57 +1380,58 @@ export const parse = (s: string): Option<number> => {
|
|
|
943
1380
|
return option.none
|
|
944
1381
|
}
|
|
945
1382
|
const n = Number(s)
|
|
946
|
-
return Number.isNaN(n)
|
|
947
|
-
? option.none
|
|
948
|
-
: option.some(n)
|
|
1383
|
+
return Number.isNaN(n) ? option.none : option.some(n)
|
|
949
1384
|
}
|
|
950
1385
|
|
|
951
1386
|
/**
|
|
952
1387
|
* Returns the number rounded with the given precision.
|
|
953
1388
|
*
|
|
1389
|
+
* @memberof Number
|
|
1390
|
+
* @since 3.8.0
|
|
1391
|
+
* @category math
|
|
954
1392
|
* @example
|
|
1393
|
+
*
|
|
955
1394
|
* ```ts
|
|
956
|
-
* import * as assert from "node:assert"
|
|
1395
|
+
* import * as assert from "node:assert/strict"
|
|
957
1396
|
* import { round } from "effect/Number"
|
|
958
1397
|
*
|
|
959
|
-
* assert.
|
|
960
|
-
* assert.
|
|
1398
|
+
* assert.equal(round(1.1234, 2), 1.12)
|
|
1399
|
+
* assert.equal(round(1.567, 2), 1.57)
|
|
961
1400
|
* ```
|
|
962
|
-
*
|
|
963
|
-
* @category math
|
|
964
|
-
* @since 3.8.0
|
|
965
1401
|
*/
|
|
966
1402
|
export const round: {
|
|
967
1403
|
/**
|
|
968
1404
|
* Returns the number rounded with the given precision.
|
|
969
1405
|
*
|
|
1406
|
+
* @memberof Number
|
|
1407
|
+
* @since 3.8.0
|
|
1408
|
+
* @category math
|
|
970
1409
|
* @example
|
|
1410
|
+
*
|
|
971
1411
|
* ```ts
|
|
972
|
-
* import * as assert from "node:assert"
|
|
1412
|
+
* import * as assert from "node:assert/strict"
|
|
973
1413
|
* import { round } from "effect/Number"
|
|
974
1414
|
*
|
|
975
|
-
* assert.
|
|
976
|
-
* assert.
|
|
1415
|
+
* assert.equal(round(1.1234, 2), 1.12)
|
|
1416
|
+
* assert.equal(round(1.567, 2), 1.57)
|
|
977
1417
|
* ```
|
|
978
|
-
*
|
|
979
|
-
* @category math
|
|
980
|
-
* @since 3.8.0
|
|
981
1418
|
*/
|
|
982
1419
|
(precision: number): (self: number) => number
|
|
983
1420
|
/**
|
|
984
1421
|
* Returns the number rounded with the given precision.
|
|
985
1422
|
*
|
|
1423
|
+
* @memberof Number
|
|
1424
|
+
* @since 3.8.0
|
|
1425
|
+
* @category math
|
|
986
1426
|
* @example
|
|
1427
|
+
*
|
|
987
1428
|
* ```ts
|
|
988
|
-
* import * as assert from "node:assert"
|
|
1429
|
+
* import * as assert from "node:assert/strict"
|
|
989
1430
|
* import { round } from "effect/Number"
|
|
990
1431
|
*
|
|
991
|
-
* assert.
|
|
992
|
-
* assert.
|
|
1432
|
+
* assert.equal(round(1.1234, 2), 1.12)
|
|
1433
|
+
* assert.equal(round(1.567, 2), 1.57)
|
|
993
1434
|
* ```
|
|
994
|
-
*
|
|
995
|
-
* @category math
|
|
996
|
-
* @since 3.8.0
|
|
997
1435
|
*/
|
|
998
1436
|
(self: number, precision: number): number
|
|
999
1437
|
} = dual(2, (self: number, precision: number): number => {
|