effect 3.16.13 → 3.16.14
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/Predicate.js +516 -200
- package/dist/cjs/Predicate.js.map +1 -1
- package/dist/cjs/Schema.js +2 -2
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/internal/channel.js +2 -2
- package/dist/cjs/internal/channel.js.map +1 -1
- package/dist/cjs/internal/core-effect.js +1 -0
- package/dist/cjs/internal/core-effect.js.map +1 -1
- package/dist/cjs/internal/dataSource.js +2 -2
- package/dist/cjs/internal/dataSource.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +1 -1
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/groupBy.js +2 -2
- package/dist/cjs/internal/groupBy.js.map +1 -1
- package/dist/cjs/internal/sink.js +4 -4
- package/dist/cjs/internal/sink.js.map +1 -1
- package/dist/cjs/internal/stm/stm.js +3 -3
- package/dist/cjs/internal/stm/stm.js.map +1 -1
- package/dist/cjs/internal/stream.js +5 -5
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Effect.d.ts +1 -1
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Predicate.d.ts +1190 -375
- package/dist/dts/Predicate.d.ts.map +1 -1
- package/dist/dts/index.d.ts +15 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/core-effect.d.ts.map +1 -1
- package/dist/dts/internal/stm/stm.d.ts.map +1 -1
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/Predicate.js +516 -200
- package/dist/esm/Predicate.js.map +1 -1
- package/dist/esm/Schema.js +2 -2
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/channel.js +2 -2
- package/dist/esm/internal/channel.js.map +1 -1
- package/dist/esm/internal/core-effect.js +1 -0
- package/dist/esm/internal/core-effect.js.map +1 -1
- package/dist/esm/internal/dataSource.js +2 -2
- package/dist/esm/internal/dataSource.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +1 -1
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/groupBy.js +2 -2
- package/dist/esm/internal/groupBy.js.map +1 -1
- package/dist/esm/internal/sink.js +4 -4
- package/dist/esm/internal/sink.js.map +1 -1
- package/dist/esm/internal/stm/stm.js +3 -3
- package/dist/esm/internal/stm/stm.js.map +1 -1
- package/dist/esm/internal/stream.js +5 -5
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +1 -1
- package/src/Effect.ts +1 -1
- package/src/Predicate.ts +1213 -377
- package/src/Schema.ts +2 -2
- package/src/index.ts +15 -0
- package/src/internal/channel.ts +2 -2
- package/src/internal/core-effect.ts +1 -0
- package/src/internal/dataSource.ts +12 -14
- package/src/internal/fiberRuntime.ts +2 -2
- package/src/internal/groupBy.ts +12 -14
- package/src/internal/sink.ts +13 -15
- package/src/internal/stm/stm.ts +16 -20
- package/src/internal/stream.ts +17 -23
- package/src/internal/version.ts +1 -1
package/dist/cjs/Predicate.js
CHANGED
|
@@ -6,23 +6,45 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.xor = exports.tuple = exports.struct = exports.some = exports.productMany = exports.product = exports.or = exports.not = exports.nor = exports.nand = exports.mapInput = exports.isUnknown = exports.isUndefined = exports.isUint8Array = exports.isTupleOfAtLeast = exports.isTupleOf = exports.isTruthy = exports.isTagged = exports.isSymbol = exports.isString = exports.isSet = exports.isRegExp = exports.isRecordOrArray = exports.isRecord = exports.isReadonlyRecord = exports.isPropertyKey = exports.isPromiseLike = exports.isPromise = exports.isObject = exports.isNumber = exports.isNullable = exports.isNull = exports.isNotUndefined = exports.isNotNullable = exports.isNotNull = exports.isNever = exports.isMap = exports.isIterable = exports.isFunction = exports.isError = exports.isDate = exports.isBoolean = exports.isBigInt = exports.implies = exports.hasProperty = exports.every = exports.eqv = exports.compose = exports.and = exports.all = void 0;
|
|
7
7
|
var _Function = require("./Function.js");
|
|
8
8
|
/**
|
|
9
|
+
* This module provides a collection of functions for working with predicates and refinements.
|
|
10
|
+
*
|
|
11
|
+
* A `Predicate<A>` is a function that takes a value of type `A` and returns a boolean.
|
|
12
|
+
* It is used to check if a value satisfies a certain condition.
|
|
13
|
+
*
|
|
14
|
+
* A `Refinement<A, B>` is a special type of predicate that not only checks a condition
|
|
15
|
+
* but also provides a type guard, allowing TypeScript to narrow the type of the input
|
|
16
|
+
* value from `A` to a more specific type `B` within a conditional block.
|
|
17
|
+
*
|
|
18
|
+
* The module includes:
|
|
19
|
+
* - Basic predicates and refinements for common types (e.g., `isString`, `isNumber`).
|
|
20
|
+
* - Combinators to create new predicates from existing ones (e.g., `and`, `or`, `not`).
|
|
21
|
+
* - Advanced combinators for working with data structures (e.g., `tuple`, `struct`).
|
|
22
|
+
* - Type-level utilities for inspecting predicate and refinement types.
|
|
23
|
+
*
|
|
9
24
|
* @since 2.0.0
|
|
10
25
|
*/
|
|
11
26
|
|
|
12
27
|
/**
|
|
13
|
-
*
|
|
28
|
+
* Transforms a `Predicate<A>` into a `Predicate<B>` by applying a function `(b: B) => A`
|
|
29
|
+
* to the input before passing it to the predicate. This is also known as "contramap" or
|
|
30
|
+
* "pre-composition".
|
|
14
31
|
*
|
|
15
32
|
* @example
|
|
16
33
|
* ```ts
|
|
17
|
-
* import * as assert from "node:assert"
|
|
18
34
|
* import { Predicate, Number } from "effect"
|
|
35
|
+
* import * as assert from "node:assert"
|
|
36
|
+
*
|
|
37
|
+
* // A predicate on numbers
|
|
38
|
+
* const isPositive: Predicate.Predicate<number> = Number.greaterThan(0)
|
|
19
39
|
*
|
|
20
|
-
*
|
|
40
|
+
* // A function from `string` to `number`
|
|
41
|
+
* const stringLength = (s: string): number => s.length
|
|
21
42
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* assert.
|
|
43
|
+
* // Create a new predicate on strings by mapping the input
|
|
44
|
+
* const hasPositiveLength = Predicate.mapInput(isPositive, stringLength)
|
|
45
|
+
*
|
|
46
|
+
* assert.strictEqual(hasPositiveLength("hello"), true)
|
|
47
|
+
* assert.strictEqual(hasPositiveLength(""), false)
|
|
26
48
|
* ```
|
|
27
49
|
*
|
|
28
50
|
* @category combinators
|
|
@@ -30,23 +52,24 @@ var _Function = require("./Function.js");
|
|
|
30
52
|
*/
|
|
31
53
|
const mapInput = exports.mapInput = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => b => self(f(b)));
|
|
32
54
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* An `Array` is considered to be a `TupleOf` if its length is exactly `N`.
|
|
55
|
+
* A refinement that checks if a `ReadonlyArray<T>` is a tuple with exactly `N` elements.
|
|
56
|
+
* If the check is successful, the type is narrowed to `TupleOf<N, T>`.
|
|
36
57
|
*
|
|
37
58
|
* @example
|
|
38
59
|
* ```ts
|
|
39
60
|
* import * as assert from "node:assert"
|
|
40
61
|
* import { isTupleOf } from "effect/Predicate"
|
|
41
62
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* assert.
|
|
63
|
+
* const isTupleOf3 = isTupleOf(3)
|
|
64
|
+
*
|
|
65
|
+
* assert.strictEqual(isTupleOf3([1, 2, 3]), true);
|
|
66
|
+
* assert.strictEqual(isTupleOf3([1, 2]), false);
|
|
45
67
|
*
|
|
46
68
|
* const arr: number[] = [1, 2, 3];
|
|
47
69
|
* if (isTupleOf(arr, 3)) {
|
|
48
|
-
*
|
|
49
|
-
*
|
|
70
|
+
* // The type of arr is now [number, number, number]
|
|
71
|
+
* const [a, b, c] = arr;
|
|
72
|
+
* assert.deepStrictEqual([a, b, c], [1, 2, 3])
|
|
50
73
|
* }
|
|
51
74
|
* ```
|
|
52
75
|
*
|
|
@@ -55,23 +78,25 @@ const mapInput = exports.mapInput = /*#__PURE__*/(0, _Function.dual)(2, (self, f
|
|
|
55
78
|
*/
|
|
56
79
|
const isTupleOf = exports.isTupleOf = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => self.length === n);
|
|
57
80
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* An `Array` is considered to be a `TupleOfAtLeast` if its length is at least `N`.
|
|
81
|
+
* A refinement that checks if a `ReadonlyArray<T>` is a tuple with at least `N` elements.
|
|
82
|
+
* If the check is successful, the type is narrowed to `TupleOfAtLeast<N, T>`.
|
|
61
83
|
*
|
|
62
84
|
* @example
|
|
63
85
|
* ```ts
|
|
64
86
|
* import * as assert from "node:assert"
|
|
65
87
|
* import { isTupleOfAtLeast } from "effect/Predicate"
|
|
66
88
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* assert.
|
|
89
|
+
* const isTupleOfAtLeast3 = isTupleOfAtLeast(3)
|
|
90
|
+
*
|
|
91
|
+
* assert.strictEqual(isTupleOfAtLeast3([1, 2, 3]), true);
|
|
92
|
+
* assert.strictEqual(isTupleOfAtLeast3([1, 2, 3, 4]), true);
|
|
93
|
+
* assert.strictEqual(isTupleOfAtLeast3([1, 2]), false);
|
|
70
94
|
*
|
|
71
95
|
* const arr: number[] = [1, 2, 3, 4];
|
|
72
96
|
* if (isTupleOfAtLeast(arr, 3)) {
|
|
73
|
-
*
|
|
74
|
-
*
|
|
97
|
+
* // The type of arr is now [number, number, number, ...number[]]
|
|
98
|
+
* const [a, b, c] = arr;
|
|
99
|
+
* assert.deepStrictEqual([a, b, c], [1, 2, 3])
|
|
75
100
|
* }
|
|
76
101
|
* ```
|
|
77
102
|
*
|
|
@@ -80,16 +105,22 @@ const isTupleOf = exports.isTupleOf = /*#__PURE__*/(0, _Function.dual)(2, (self,
|
|
|
80
105
|
*/
|
|
81
106
|
const isTupleOfAtLeast = exports.isTupleOfAtLeast = /*#__PURE__*/(0, _Function.dual)(2, (self, n) => self.length >= n);
|
|
82
107
|
/**
|
|
83
|
-
*
|
|
108
|
+
* A predicate that checks if a value is "truthy" in JavaScript.
|
|
109
|
+
* Fails for `false`, `0`, `-0`, `0n`, `""`, `null`, `undefined`, and `NaN`.
|
|
84
110
|
*
|
|
85
111
|
* @example
|
|
86
112
|
* ```ts
|
|
87
113
|
* import * as assert from "node:assert"
|
|
88
114
|
* import { isTruthy } from "effect/Predicate"
|
|
89
115
|
*
|
|
90
|
-
* assert.
|
|
91
|
-
* assert.
|
|
92
|
-
* assert.
|
|
116
|
+
* assert.strictEqual(isTruthy(1), true)
|
|
117
|
+
* assert.strictEqual(isTruthy("hello"), true)
|
|
118
|
+
* assert.strictEqual(isTruthy({}), true)
|
|
119
|
+
*
|
|
120
|
+
* assert.strictEqual(isTruthy(0), false)
|
|
121
|
+
* assert.strictEqual(isTruthy(""), false)
|
|
122
|
+
* assert.strictEqual(isTruthy(null), false)
|
|
123
|
+
* assert.strictEqual(isTruthy(undefined), false)
|
|
93
124
|
* ```
|
|
94
125
|
*
|
|
95
126
|
* @category guards
|
|
@@ -97,18 +128,18 @@ const isTupleOfAtLeast = exports.isTupleOfAtLeast = /*#__PURE__*/(0, _Function.d
|
|
|
97
128
|
*/
|
|
98
129
|
const isTruthy = input => !!input;
|
|
99
130
|
/**
|
|
100
|
-
*
|
|
131
|
+
* A refinement that checks if a value is a `Set`.
|
|
101
132
|
*
|
|
102
133
|
* @example
|
|
103
134
|
* ```ts
|
|
104
135
|
* import * as assert from "node:assert"
|
|
105
136
|
* import { isSet } from "effect/Predicate"
|
|
106
137
|
*
|
|
107
|
-
* assert.
|
|
108
|
-
* assert.
|
|
109
|
-
*
|
|
110
|
-
* assert.
|
|
111
|
-
* assert.
|
|
138
|
+
* assert.strictEqual(isSet(new Set([1, 2])), true)
|
|
139
|
+
* assert.strictEqual(isSet(new Set()), true)
|
|
140
|
+
*
|
|
141
|
+
* assert.strictEqual(isSet({}), false)
|
|
142
|
+
* assert.strictEqual(isSet([1, 2]), false)
|
|
112
143
|
* ```
|
|
113
144
|
*
|
|
114
145
|
* @category guards
|
|
@@ -117,17 +148,17 @@ const isTruthy = input => !!input;
|
|
|
117
148
|
exports.isTruthy = isTruthy;
|
|
118
149
|
const isSet = input => input instanceof Set;
|
|
119
150
|
/**
|
|
120
|
-
*
|
|
151
|
+
* A refinement that checks if a value is a `Map`.
|
|
121
152
|
*
|
|
122
153
|
* @example
|
|
123
154
|
* ```ts
|
|
124
155
|
* import * as assert from "node:assert"
|
|
125
156
|
* import { isMap } from "effect/Predicate"
|
|
126
157
|
*
|
|
127
|
-
* assert.
|
|
128
|
-
*
|
|
129
|
-
* assert.
|
|
130
|
-
* assert.
|
|
158
|
+
* assert.strictEqual(isMap(new Map()), true)
|
|
159
|
+
*
|
|
160
|
+
* assert.strictEqual(isMap({}), false)
|
|
161
|
+
* assert.strictEqual(isMap(new Set()), false)
|
|
131
162
|
* ```
|
|
132
163
|
*
|
|
133
164
|
* @category guards
|
|
@@ -136,16 +167,18 @@ const isSet = input => input instanceof Set;
|
|
|
136
167
|
exports.isSet = isSet;
|
|
137
168
|
const isMap = input => input instanceof Map;
|
|
138
169
|
/**
|
|
139
|
-
*
|
|
170
|
+
* A refinement that checks if a value is a `string`.
|
|
140
171
|
*
|
|
141
172
|
* @example
|
|
142
173
|
* ```ts
|
|
143
174
|
* import * as assert from "node:assert"
|
|
144
175
|
* import { isString } from "effect/Predicate"
|
|
145
176
|
*
|
|
146
|
-
* assert.
|
|
177
|
+
* assert.strictEqual(isString("hello"), true)
|
|
178
|
+
* assert.strictEqual(isString(""), true)
|
|
147
179
|
*
|
|
148
|
-
* assert.
|
|
180
|
+
* assert.strictEqual(isString(123), false)
|
|
181
|
+
* assert.strictEqual(isString(null), false)
|
|
149
182
|
* ```
|
|
150
183
|
*
|
|
151
184
|
* @category guards
|
|
@@ -154,16 +187,20 @@ const isMap = input => input instanceof Map;
|
|
|
154
187
|
exports.isMap = isMap;
|
|
155
188
|
const isString = input => typeof input === "string";
|
|
156
189
|
/**
|
|
157
|
-
*
|
|
190
|
+
* A refinement that checks if a value is a `number`. Note that this
|
|
191
|
+
* check returns `false` for `NaN`.
|
|
158
192
|
*
|
|
159
193
|
* @example
|
|
160
194
|
* ```ts
|
|
161
195
|
* import * as assert from "node:assert"
|
|
162
196
|
* import { isNumber } from "effect/Predicate"
|
|
163
197
|
*
|
|
164
|
-
* assert.
|
|
198
|
+
* assert.strictEqual(isNumber(123), true)
|
|
199
|
+
* assert.strictEqual(isNumber(0), true)
|
|
200
|
+
* assert.strictEqual(isNumber(-1.5), true)
|
|
165
201
|
*
|
|
166
|
-
* assert.
|
|
202
|
+
* assert.strictEqual(isNumber("123"), false)
|
|
203
|
+
* assert.strictEqual(isNumber(NaN), false) // Special case: NaN is a number type but returns false
|
|
167
204
|
* ```
|
|
168
205
|
*
|
|
169
206
|
* @category guards
|
|
@@ -172,16 +209,18 @@ const isString = input => typeof input === "string";
|
|
|
172
209
|
exports.isString = isString;
|
|
173
210
|
const isNumber = input => typeof input === "number";
|
|
174
211
|
/**
|
|
175
|
-
*
|
|
212
|
+
* A refinement that checks if a value is a `boolean`.
|
|
176
213
|
*
|
|
177
214
|
* @example
|
|
178
215
|
* ```ts
|
|
179
216
|
* import * as assert from "node:assert"
|
|
180
217
|
* import { isBoolean } from "effect/Predicate"
|
|
181
218
|
*
|
|
182
|
-
* assert.
|
|
219
|
+
* assert.strictEqual(isBoolean(true), true)
|
|
220
|
+
* assert.strictEqual(isBoolean(false), true)
|
|
183
221
|
*
|
|
184
|
-
* assert.
|
|
222
|
+
* assert.strictEqual(isBoolean("true"), false)
|
|
223
|
+
* assert.strictEqual(isBoolean(0), false)
|
|
185
224
|
* ```
|
|
186
225
|
*
|
|
187
226
|
* @category guards
|
|
@@ -190,16 +229,17 @@ const isNumber = input => typeof input === "number";
|
|
|
190
229
|
exports.isNumber = isNumber;
|
|
191
230
|
const isBoolean = input => typeof input === "boolean";
|
|
192
231
|
/**
|
|
193
|
-
*
|
|
232
|
+
* A refinement that checks if a value is a `bigint`.
|
|
194
233
|
*
|
|
195
234
|
* @example
|
|
196
235
|
* ```ts
|
|
197
236
|
* import * as assert from "node:assert"
|
|
198
237
|
* import { isBigInt } from "effect/Predicate"
|
|
199
238
|
*
|
|
200
|
-
* assert.
|
|
239
|
+
* assert.strictEqual(isBigInt(1n), true)
|
|
201
240
|
*
|
|
202
|
-
* assert.
|
|
241
|
+
* assert.strictEqual(isBigInt(1), false)
|
|
242
|
+
* assert.strictEqual(isBigInt("1"), false)
|
|
203
243
|
* ```
|
|
204
244
|
*
|
|
205
245
|
* @category guards
|
|
@@ -208,16 +248,16 @@ const isBoolean = input => typeof input === "boolean";
|
|
|
208
248
|
exports.isBoolean = isBoolean;
|
|
209
249
|
const isBigInt = input => typeof input === "bigint";
|
|
210
250
|
/**
|
|
211
|
-
*
|
|
251
|
+
* A refinement that checks if a value is a `symbol`.
|
|
212
252
|
*
|
|
213
253
|
* @example
|
|
214
254
|
* ```ts
|
|
215
255
|
* import * as assert from "node:assert"
|
|
216
256
|
* import { isSymbol } from "effect/Predicate"
|
|
217
257
|
*
|
|
218
|
-
* assert.
|
|
258
|
+
* assert.strictEqual(isSymbol(Symbol.for("a")), true)
|
|
219
259
|
*
|
|
220
|
-
* assert.
|
|
260
|
+
* assert.strictEqual(isSymbol("a"), false)
|
|
221
261
|
* ```
|
|
222
262
|
*
|
|
223
263
|
* @category guards
|
|
@@ -226,20 +266,24 @@ const isBigInt = input => typeof input === "bigint";
|
|
|
226
266
|
exports.isBigInt = isBigInt;
|
|
227
267
|
const isSymbol = input => typeof input === "symbol";
|
|
228
268
|
// TODO: make public
|
|
229
|
-
/**
|
|
269
|
+
/**
|
|
270
|
+
* A refinement that checks if a value is a valid `PropertyKey` (a `string`, `number`, or `symbol`).
|
|
271
|
+
* @internal
|
|
272
|
+
*/
|
|
230
273
|
exports.isSymbol = isSymbol;
|
|
231
274
|
const isPropertyKey = u => isString(u) || isNumber(u) || isSymbol(u);
|
|
232
275
|
/**
|
|
233
|
-
*
|
|
276
|
+
* A refinement that checks if a value is a `Function`.
|
|
234
277
|
*
|
|
235
278
|
* @example
|
|
236
279
|
* ```ts
|
|
237
280
|
* import * as assert from "node:assert"
|
|
238
281
|
* import { isFunction } from "effect/Predicate"
|
|
239
282
|
*
|
|
240
|
-
* assert.
|
|
283
|
+
* assert.strictEqual(isFunction(() => {}), true)
|
|
284
|
+
* assert.strictEqual(isFunction(isFunction), true)
|
|
241
285
|
*
|
|
242
|
-
* assert.
|
|
286
|
+
* assert.strictEqual(isFunction("function"), false)
|
|
243
287
|
* ```
|
|
244
288
|
*
|
|
245
289
|
* @category guards
|
|
@@ -248,17 +292,17 @@ const isPropertyKey = u => isString(u) || isNumber(u) || isSymbol(u);
|
|
|
248
292
|
exports.isPropertyKey = isPropertyKey;
|
|
249
293
|
const isFunction = exports.isFunction = _Function.isFunction;
|
|
250
294
|
/**
|
|
251
|
-
*
|
|
295
|
+
* A refinement that checks if a value is `undefined`.
|
|
252
296
|
*
|
|
253
297
|
* @example
|
|
254
298
|
* ```ts
|
|
255
299
|
* import * as assert from "node:assert"
|
|
256
300
|
* import { isUndefined } from "effect/Predicate"
|
|
257
301
|
*
|
|
258
|
-
* assert.
|
|
302
|
+
* assert.strictEqual(isUndefined(undefined), true)
|
|
259
303
|
*
|
|
260
|
-
* assert.
|
|
261
|
-
* assert.
|
|
304
|
+
* assert.strictEqual(isUndefined(null), false)
|
|
305
|
+
* assert.strictEqual(isUndefined("undefined"), false)
|
|
262
306
|
* ```
|
|
263
307
|
*
|
|
264
308
|
* @category guards
|
|
@@ -266,17 +310,17 @@ const isFunction = exports.isFunction = _Function.isFunction;
|
|
|
266
310
|
*/
|
|
267
311
|
const isUndefined = input => input === undefined;
|
|
268
312
|
/**
|
|
269
|
-
*
|
|
313
|
+
* A refinement that checks if a value is not `undefined`.
|
|
270
314
|
*
|
|
271
315
|
* @example
|
|
272
316
|
* ```ts
|
|
273
317
|
* import * as assert from "node:assert"
|
|
274
318
|
* import { isNotUndefined } from "effect/Predicate"
|
|
275
319
|
*
|
|
276
|
-
* assert.
|
|
277
|
-
* assert.
|
|
320
|
+
* assert.strictEqual(isNotUndefined(null), true)
|
|
321
|
+
* assert.strictEqual(isNotUndefined("value"), true)
|
|
278
322
|
*
|
|
279
|
-
* assert.
|
|
323
|
+
* assert.strictEqual(isNotUndefined(undefined), false)
|
|
280
324
|
* ```
|
|
281
325
|
*
|
|
282
326
|
* @category guards
|
|
@@ -285,17 +329,17 @@ const isUndefined = input => input === undefined;
|
|
|
285
329
|
exports.isUndefined = isUndefined;
|
|
286
330
|
const isNotUndefined = input => input !== undefined;
|
|
287
331
|
/**
|
|
288
|
-
*
|
|
332
|
+
* A refinement that checks if a value is `null`.
|
|
289
333
|
*
|
|
290
334
|
* @example
|
|
291
335
|
* ```ts
|
|
292
336
|
* import * as assert from "node:assert"
|
|
293
337
|
* import { isNull } from "effect/Predicate"
|
|
294
338
|
*
|
|
295
|
-
* assert.
|
|
339
|
+
* assert.strictEqual(isNull(null), true)
|
|
296
340
|
*
|
|
297
|
-
* assert.
|
|
298
|
-
* assert.
|
|
341
|
+
* assert.strictEqual(isNull(undefined), false)
|
|
342
|
+
* assert.strictEqual(isNull("null"), false)
|
|
299
343
|
* ```
|
|
300
344
|
*
|
|
301
345
|
* @category guards
|
|
@@ -304,17 +348,17 @@ const isNotUndefined = input => input !== undefined;
|
|
|
304
348
|
exports.isNotUndefined = isNotUndefined;
|
|
305
349
|
const isNull = input => input === null;
|
|
306
350
|
/**
|
|
307
|
-
*
|
|
351
|
+
* A refinement that checks if a value is not `null`.
|
|
308
352
|
*
|
|
309
353
|
* @example
|
|
310
354
|
* ```ts
|
|
311
355
|
* import * as assert from "node:assert"
|
|
312
356
|
* import { isNotNull } from "effect/Predicate"
|
|
313
357
|
*
|
|
314
|
-
* assert.
|
|
315
|
-
* assert.
|
|
358
|
+
* assert.strictEqual(isNotNull(undefined), true)
|
|
359
|
+
* assert.strictEqual(isNotNull("value"), true)
|
|
316
360
|
*
|
|
317
|
-
* assert.
|
|
361
|
+
* assert.strictEqual(isNotNull(null), false)
|
|
318
362
|
* ```
|
|
319
363
|
*
|
|
320
364
|
* @category guards
|
|
@@ -323,17 +367,16 @@ const isNull = input => input === null;
|
|
|
323
367
|
exports.isNull = isNull;
|
|
324
368
|
const isNotNull = input => input !== null;
|
|
325
369
|
/**
|
|
326
|
-
* A
|
|
370
|
+
* A refinement that always returns `false`. The type is narrowed to `never`.
|
|
327
371
|
*
|
|
328
372
|
* @example
|
|
329
373
|
* ```ts
|
|
330
374
|
* import * as assert from "node:assert"
|
|
331
375
|
* import { isNever } from "effect/Predicate"
|
|
332
376
|
*
|
|
333
|
-
* assert.
|
|
334
|
-
* assert.
|
|
335
|
-
* assert.
|
|
336
|
-
* assert.deepStrictEqual(isNever([]), false)
|
|
377
|
+
* assert.strictEqual(isNever(1), false)
|
|
378
|
+
* assert.strictEqual(isNever(null), false)
|
|
379
|
+
* assert.strictEqual(isNever({}), false)
|
|
337
380
|
* ```
|
|
338
381
|
*
|
|
339
382
|
* @category guards
|
|
@@ -342,18 +385,16 @@ const isNotNull = input => input !== null;
|
|
|
342
385
|
exports.isNotNull = isNotNull;
|
|
343
386
|
const isNever = _ => false;
|
|
344
387
|
/**
|
|
345
|
-
* A
|
|
388
|
+
* A refinement that always returns `true`. The type is narrowed to `unknown`.
|
|
346
389
|
*
|
|
347
390
|
* @example
|
|
348
391
|
* ```ts
|
|
349
392
|
* import * as assert from "node:assert"
|
|
350
393
|
* import { isUnknown } from "effect/Predicate"
|
|
351
394
|
*
|
|
352
|
-
* assert.
|
|
353
|
-
* assert.
|
|
354
|
-
*
|
|
355
|
-
* assert.deepStrictEqual(isUnknown({}), true)
|
|
356
|
-
* assert.deepStrictEqual(isUnknown([]), true)
|
|
395
|
+
* assert.strictEqual(isUnknown(1), true)
|
|
396
|
+
* assert.strictEqual(isUnknown(null), true)
|
|
397
|
+
* assert.strictEqual(isUnknown({}), true)
|
|
357
398
|
* ```
|
|
358
399
|
*
|
|
359
400
|
* @category guards
|
|
@@ -361,31 +402,53 @@ const isNever = _ => false;
|
|
|
361
402
|
*/
|
|
362
403
|
exports.isNever = isNever;
|
|
363
404
|
const isUnknown = _ => true;
|
|
364
|
-
/**
|
|
405
|
+
/**
|
|
406
|
+
* Checks if the input is an object or an array.
|
|
407
|
+
* @internal
|
|
408
|
+
*/
|
|
365
409
|
exports.isUnknown = isUnknown;
|
|
366
410
|
const isRecordOrArray = input => typeof input === "object" && input !== null;
|
|
367
411
|
/**
|
|
368
|
-
*
|
|
412
|
+
* A refinement that checks if a value is an `object`. Note that in JavaScript,
|
|
413
|
+
* arrays and functions are also considered objects.
|
|
369
414
|
*
|
|
370
415
|
* @example
|
|
371
416
|
* ```ts
|
|
372
417
|
* import * as assert from "node:assert"
|
|
373
418
|
* import { isObject } from "effect/Predicate"
|
|
374
419
|
*
|
|
375
|
-
* assert.
|
|
376
|
-
* assert.
|
|
420
|
+
* assert.strictEqual(isObject({}), true)
|
|
421
|
+
* assert.strictEqual(isObject([]), true)
|
|
422
|
+
* assert.strictEqual(isObject(() => {}), true)
|
|
377
423
|
*
|
|
378
|
-
* assert.
|
|
379
|
-
* assert.
|
|
424
|
+
* assert.strictEqual(isObject(null), false)
|
|
425
|
+
* assert.strictEqual(isObject("hello"), false)
|
|
380
426
|
* ```
|
|
381
427
|
*
|
|
382
428
|
* @category guards
|
|
383
429
|
* @since 2.0.0
|
|
430
|
+
* @see isRecord to check for plain objects (excluding arrays and functions).
|
|
384
431
|
*/
|
|
385
432
|
exports.isRecordOrArray = isRecordOrArray;
|
|
386
433
|
const isObject = input => isRecordOrArray(input) || isFunction(input);
|
|
387
434
|
/**
|
|
388
|
-
*
|
|
435
|
+
* A refinement that checks if a value is an object-like value and has a specific property key.
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```ts
|
|
439
|
+
* import * as assert from "node:assert"
|
|
440
|
+
* import { hasProperty } from "effect/Predicate"
|
|
441
|
+
*
|
|
442
|
+
* assert.strictEqual(hasProperty({ a: 1 }, "a"), true)
|
|
443
|
+
* assert.strictEqual(hasProperty({ a: 1 }, "b"), false)
|
|
444
|
+
*
|
|
445
|
+
* const value: unknown = { name: "Alice" };
|
|
446
|
+
* if (hasProperty(value, "name")) {
|
|
447
|
+
* // The type of `value` is narrowed to `{ name: unknown }`
|
|
448
|
+
* // and we can safely access `value.name`
|
|
449
|
+
* console.log(value.name)
|
|
450
|
+
* }
|
|
451
|
+
* ```
|
|
389
452
|
*
|
|
390
453
|
* @category guards
|
|
391
454
|
* @since 2.0.0
|
|
@@ -393,19 +456,29 @@ const isObject = input => isRecordOrArray(input) || isFunction(input);
|
|
|
393
456
|
exports.isObject = isObject;
|
|
394
457
|
const hasProperty = exports.hasProperty = /*#__PURE__*/(0, _Function.dual)(2, (self, property) => isObject(self) && property in self);
|
|
395
458
|
/**
|
|
396
|
-
*
|
|
459
|
+
* A refinement that checks if a value is an object with a `_tag` property
|
|
460
|
+
* that matches the given tag. This is a powerful tool for working with
|
|
461
|
+
* discriminated union types.
|
|
397
462
|
*
|
|
398
463
|
* @example
|
|
399
464
|
* ```ts
|
|
400
465
|
* import * as assert from "node:assert"
|
|
401
466
|
* import { isTagged } from "effect/Predicate"
|
|
402
467
|
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
468
|
+
* type Shape = { _tag: "circle"; radius: number } | { _tag: "square"; side: number }
|
|
469
|
+
*
|
|
470
|
+
* const isCircle = isTagged("circle")
|
|
471
|
+
*
|
|
472
|
+
* const shape1: Shape = { _tag: "circle", radius: 10 }
|
|
473
|
+
* const shape2: Shape = { _tag: "square", side: 5 }
|
|
474
|
+
*
|
|
475
|
+
* assert.strictEqual(isCircle(shape1), true)
|
|
476
|
+
* assert.strictEqual(isCircle(shape2), false)
|
|
477
|
+
*
|
|
478
|
+
* if (isCircle(shape1)) {
|
|
479
|
+
* // shape1 is now narrowed to { _tag: "circle"; radius: number }
|
|
480
|
+
* assert.strictEqual(shape1.radius, 10)
|
|
481
|
+
* }
|
|
409
482
|
* ```
|
|
410
483
|
*
|
|
411
484
|
* @category guards
|
|
@@ -413,56 +486,60 @@ const hasProperty = exports.hasProperty = /*#__PURE__*/(0, _Function.dual)(2, (s
|
|
|
413
486
|
*/
|
|
414
487
|
const isTagged = exports.isTagged = /*#__PURE__*/(0, _Function.dual)(2, (self, tag) => hasProperty(self, "_tag") && self["_tag"] === tag);
|
|
415
488
|
/**
|
|
416
|
-
* A
|
|
489
|
+
* A refinement that checks if a value is either `null` or `undefined`.
|
|
417
490
|
*
|
|
418
491
|
* @example
|
|
419
492
|
* ```ts
|
|
420
493
|
* import * as assert from "node:assert"
|
|
421
494
|
* import { isNullable } from "effect/Predicate"
|
|
422
495
|
*
|
|
423
|
-
* assert.
|
|
424
|
-
* assert.
|
|
496
|
+
* assert.strictEqual(isNullable(null), true)
|
|
497
|
+
* assert.strictEqual(isNullable(undefined), true)
|
|
425
498
|
*
|
|
426
|
-
* assert.
|
|
427
|
-
* assert.
|
|
499
|
+
* assert.strictEqual(isNullable(0), false)
|
|
500
|
+
* assert.strictEqual(isNullable(""), false)
|
|
428
501
|
* ```
|
|
429
502
|
*
|
|
430
503
|
* @category guards
|
|
431
504
|
* @since 2.0.0
|
|
505
|
+
* @see isNotNullable
|
|
432
506
|
*/
|
|
433
507
|
const isNullable = input => input === null || input === undefined;
|
|
434
508
|
/**
|
|
435
|
-
* A
|
|
509
|
+
* A refinement that checks if a value is neither `null` nor `undefined`.
|
|
510
|
+
* The type is narrowed to `NonNullable<A>`.
|
|
436
511
|
*
|
|
437
512
|
* @example
|
|
438
513
|
* ```ts
|
|
439
514
|
* import * as assert from "node:assert"
|
|
440
515
|
* import { isNotNullable } from "effect/Predicate"
|
|
441
516
|
*
|
|
442
|
-
* assert.
|
|
443
|
-
* assert.
|
|
517
|
+
* assert.strictEqual(isNotNullable(0), true)
|
|
518
|
+
* assert.strictEqual(isNotNullable("hello"), true)
|
|
444
519
|
*
|
|
445
|
-
* assert.
|
|
446
|
-
* assert.
|
|
520
|
+
* assert.strictEqual(isNotNullable(null), false)
|
|
521
|
+
* assert.strictEqual(isNotNullable(undefined), false)
|
|
447
522
|
* ```
|
|
448
523
|
*
|
|
449
524
|
* @category guards
|
|
450
525
|
* @since 2.0.0
|
|
526
|
+
* @see isNullable
|
|
451
527
|
*/
|
|
452
528
|
exports.isNullable = isNullable;
|
|
453
529
|
const isNotNullable = input => input !== null && input !== undefined;
|
|
454
530
|
/**
|
|
455
|
-
* A
|
|
531
|
+
* A refinement that checks if a value is an instance of `Error`.
|
|
456
532
|
*
|
|
457
533
|
* @example
|
|
458
534
|
* ```ts
|
|
459
535
|
* import * as assert from "node:assert"
|
|
460
536
|
* import { isError } from "effect/Predicate"
|
|
461
537
|
*
|
|
462
|
-
* assert.
|
|
538
|
+
* assert.strictEqual(isError(new Error("boom")), true)
|
|
539
|
+
* assert.strictEqual(isError(new TypeError("boom")), true)
|
|
463
540
|
*
|
|
464
|
-
* assert.
|
|
465
|
-
* assert.
|
|
541
|
+
* assert.strictEqual(isError({ message: "boom" }), false)
|
|
542
|
+
* assert.strictEqual(isError("boom"), false)
|
|
466
543
|
* ```
|
|
467
544
|
*
|
|
468
545
|
* @category guards
|
|
@@ -471,17 +548,17 @@ const isNotNullable = input => input !== null && input !== undefined;
|
|
|
471
548
|
exports.isNotNullable = isNotNullable;
|
|
472
549
|
const isError = input => input instanceof Error;
|
|
473
550
|
/**
|
|
474
|
-
* A
|
|
551
|
+
* A refinement that checks if a value is a `Uint8Array`.
|
|
475
552
|
*
|
|
476
553
|
* @example
|
|
477
554
|
* ```ts
|
|
478
555
|
* import * as assert from "node:assert"
|
|
479
556
|
* import { isUint8Array } from "effect/Predicate"
|
|
480
557
|
*
|
|
481
|
-
* assert.
|
|
558
|
+
* assert.strictEqual(isUint8Array(new Uint8Array()), true)
|
|
482
559
|
*
|
|
483
|
-
* assert.
|
|
484
|
-
* assert.
|
|
560
|
+
* assert.strictEqual(isUint8Array(new Uint16Array()), false)
|
|
561
|
+
* assert.strictEqual(isUint8Array([1, 2, 3]), false)
|
|
485
562
|
* ```
|
|
486
563
|
*
|
|
487
564
|
* @category guards
|
|
@@ -490,17 +567,17 @@ const isError = input => input instanceof Error;
|
|
|
490
567
|
exports.isError = isError;
|
|
491
568
|
const isUint8Array = input => input instanceof Uint8Array;
|
|
492
569
|
/**
|
|
493
|
-
* A
|
|
570
|
+
* A refinement that checks if a value is a `Date` object.
|
|
494
571
|
*
|
|
495
572
|
* @example
|
|
496
573
|
* ```ts
|
|
497
574
|
* import * as assert from "node:assert"
|
|
498
575
|
* import { isDate } from "effect/Predicate"
|
|
499
576
|
*
|
|
500
|
-
* assert.
|
|
577
|
+
* assert.strictEqual(isDate(new Date()), true)
|
|
501
578
|
*
|
|
502
|
-
* assert.
|
|
503
|
-
* assert.
|
|
579
|
+
* assert.strictEqual(isDate(Date.now()), false) // `Date.now()` returns a number
|
|
580
|
+
* assert.strictEqual(isDate("2023-01-01"), false)
|
|
504
581
|
* ```
|
|
505
582
|
*
|
|
506
583
|
* @category guards
|
|
@@ -509,18 +586,20 @@ const isUint8Array = input => input instanceof Uint8Array;
|
|
|
509
586
|
exports.isUint8Array = isUint8Array;
|
|
510
587
|
const isDate = input => input instanceof Date;
|
|
511
588
|
/**
|
|
512
|
-
* A
|
|
589
|
+
* A refinement that checks if a value is an `Iterable`.
|
|
590
|
+
* Many built-in types are iterable, such as `Array`, `string`, `Map`, and `Set`.
|
|
513
591
|
*
|
|
514
592
|
* @example
|
|
515
593
|
* ```ts
|
|
516
594
|
* import * as assert from "node:assert"
|
|
517
595
|
* import { isIterable } from "effect/Predicate"
|
|
518
596
|
*
|
|
519
|
-
* assert.
|
|
520
|
-
* assert.
|
|
597
|
+
* assert.strictEqual(isIterable([]), true)
|
|
598
|
+
* assert.strictEqual(isIterable("hello"), true)
|
|
599
|
+
* assert.strictEqual(isIterable(new Set()), true)
|
|
521
600
|
*
|
|
522
|
-
* assert.
|
|
523
|
-
* assert.
|
|
601
|
+
* assert.strictEqual(isIterable({}), false)
|
|
602
|
+
* assert.strictEqual(isIterable(123), false)
|
|
524
603
|
* ```
|
|
525
604
|
*
|
|
526
605
|
* @category guards
|
|
@@ -529,43 +608,45 @@ const isDate = input => input instanceof Date;
|
|
|
529
608
|
exports.isDate = isDate;
|
|
530
609
|
const isIterable = input => hasProperty(input, Symbol.iterator);
|
|
531
610
|
/**
|
|
532
|
-
* A
|
|
611
|
+
* A refinement that checks if a value is a record (i.e., a plain object).
|
|
612
|
+
* This check returns `false` for arrays, `null`, and functions.
|
|
533
613
|
*
|
|
534
614
|
* @example
|
|
535
615
|
* ```ts
|
|
536
616
|
* import * as assert from "node:assert"
|
|
537
617
|
* import { isRecord } from "effect/Predicate"
|
|
538
618
|
*
|
|
539
|
-
* assert.
|
|
540
|
-
* assert.
|
|
619
|
+
* assert.strictEqual(isRecord({}), true)
|
|
620
|
+
* assert.strictEqual(isRecord({ a: 1 }), true)
|
|
541
621
|
*
|
|
542
|
-
* assert.
|
|
543
|
-
* assert.
|
|
544
|
-
* assert.
|
|
545
|
-
* assert.
|
|
546
|
-
* assert.deepStrictEqual(isRecord(() => null), false)
|
|
622
|
+
* assert.strictEqual(isRecord([]), false)
|
|
623
|
+
* assert.strictEqual(isRecord(new Date()), false)
|
|
624
|
+
* assert.strictEqual(isRecord(null), false)
|
|
625
|
+
* assert.strictEqual(isRecord(() => null), false)
|
|
547
626
|
* ```
|
|
548
627
|
*
|
|
549
628
|
* @category guards
|
|
550
629
|
* @since 2.0.0
|
|
630
|
+
* @see isObject
|
|
551
631
|
*/
|
|
552
632
|
exports.isIterable = isIterable;
|
|
553
633
|
const isRecord = input => isRecordOrArray(input) && !Array.isArray(input);
|
|
554
634
|
/**
|
|
555
|
-
* A
|
|
635
|
+
* A refinement that checks if a value is a readonly record (i.e., a plain object).
|
|
636
|
+
* This check returns `false` for arrays, `null`, and functions.
|
|
637
|
+
*
|
|
638
|
+
* This is an alias for `isRecord`.
|
|
556
639
|
*
|
|
557
640
|
* @example
|
|
558
641
|
* ```ts
|
|
559
642
|
* import * as assert from "node:assert"
|
|
560
643
|
* import { isReadonlyRecord } from "effect/Predicate"
|
|
561
644
|
*
|
|
562
|
-
* assert.
|
|
563
|
-
* assert.
|
|
645
|
+
* assert.strictEqual(isReadonlyRecord({}), true)
|
|
646
|
+
* assert.strictEqual(isReadonlyRecord({ a: 1 }), true)
|
|
564
647
|
*
|
|
565
|
-
* assert.
|
|
566
|
-
* assert.
|
|
567
|
-
* assert.deepStrictEqual(isReadonlyRecord(null), false)
|
|
568
|
-
* assert.deepStrictEqual(isReadonlyRecord(undefined), false)
|
|
648
|
+
* assert.strictEqual(isReadonlyRecord([]), false)
|
|
649
|
+
* assert.strictEqual(isReadonlyRecord(null), false)
|
|
569
650
|
* ```
|
|
570
651
|
*
|
|
571
652
|
* @category guards
|
|
@@ -574,37 +655,59 @@ const isRecord = input => isRecordOrArray(input) && !Array.isArray(input);
|
|
|
574
655
|
exports.isRecord = isRecord;
|
|
575
656
|
const isReadonlyRecord = exports.isReadonlyRecord = isRecord;
|
|
576
657
|
/**
|
|
577
|
-
* A
|
|
658
|
+
* A refinement that checks if a value is a `Promise`. It performs a duck-typing check
|
|
659
|
+
* for `.then` and `.catch` methods.
|
|
578
660
|
*
|
|
579
661
|
* @example
|
|
580
662
|
* ```ts
|
|
581
663
|
* import * as assert from "node:assert"
|
|
582
664
|
* import { isPromise } from "effect/Predicate"
|
|
583
665
|
*
|
|
584
|
-
* assert.
|
|
585
|
-
* assert.
|
|
666
|
+
* assert.strictEqual(isPromise(Promise.resolve(1)), true)
|
|
667
|
+
* assert.strictEqual(isPromise(new Promise(() => {})), true)
|
|
668
|
+
*
|
|
669
|
+
* assert.strictEqual(isPromise({ then() {} }), false) // Missing .catch
|
|
670
|
+
* assert.strictEqual(isPromise({}), false)
|
|
586
671
|
* ```
|
|
587
672
|
*
|
|
588
673
|
* @category guards
|
|
589
674
|
* @since 2.0.0
|
|
675
|
+
* @see isPromiseLike
|
|
590
676
|
*/
|
|
591
677
|
const isPromise = input => hasProperty(input, "then") && "catch" in input && isFunction(input.then) && isFunction(input.catch);
|
|
592
678
|
/**
|
|
679
|
+
* A refinement that checks if a value is `PromiseLike`. It performs a duck-typing
|
|
680
|
+
* check for a `.then` method.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```ts
|
|
684
|
+
* import * as assert from "node:assert"
|
|
685
|
+
* import { isPromiseLike } from "effect/Predicate"
|
|
686
|
+
*
|
|
687
|
+
* assert.strictEqual(isPromiseLike(Promise.resolve(1)), true)
|
|
688
|
+
* assert.strictEqual(isPromiseLike({ then: () => {} }), true)
|
|
689
|
+
*
|
|
690
|
+
* assert.strictEqual(isPromiseLike({}), false)
|
|
691
|
+
* ```
|
|
692
|
+
*
|
|
593
693
|
* @category guards
|
|
594
694
|
* @since 2.0.0
|
|
695
|
+
* @see isPromise
|
|
595
696
|
*/
|
|
596
697
|
exports.isPromise = isPromise;
|
|
597
698
|
const isPromiseLike = input => hasProperty(input, "then") && isFunction(input.then);
|
|
598
699
|
/**
|
|
599
|
-
*
|
|
700
|
+
* A refinement that checks if a value is a `RegExp`.
|
|
600
701
|
*
|
|
601
702
|
* @example
|
|
602
703
|
* ```ts
|
|
603
704
|
* import * as assert from "node:assert"
|
|
604
705
|
* import { Predicate } from "effect"
|
|
605
706
|
*
|
|
606
|
-
* assert.
|
|
607
|
-
* assert.
|
|
707
|
+
* assert.strictEqual(Predicate.isRegExp(/a/), true)
|
|
708
|
+
* assert.strictEqual(Predicate.isRegExp(new RegExp("a")), true)
|
|
709
|
+
*
|
|
710
|
+
* assert.strictEqual(Predicate.isRegExp("/a/"), false)
|
|
608
711
|
* ```
|
|
609
712
|
*
|
|
610
713
|
* @category guards
|
|
@@ -613,18 +716,54 @@ const isPromiseLike = input => hasProperty(input, "then") && isFunction(input.th
|
|
|
613
716
|
exports.isPromiseLike = isPromiseLike;
|
|
614
717
|
const isRegExp = input => input instanceof RegExp;
|
|
615
718
|
/**
|
|
719
|
+
* Composes a `Refinement` with another `Refinement` or `Predicate`.
|
|
720
|
+
*
|
|
721
|
+
* This can be used to chain checks. The first refinement is applied, and if it
|
|
722
|
+
* passes, the second check is applied to the same value, potentially refining
|
|
723
|
+
* the type further.
|
|
724
|
+
*
|
|
725
|
+
* @example
|
|
726
|
+
* ```ts
|
|
727
|
+
* import { Predicate } from "effect"
|
|
728
|
+
* import * as assert from "node:assert"
|
|
729
|
+
*
|
|
730
|
+
* const isString = (u: unknown): u is string => typeof u === "string"
|
|
731
|
+
* const minLength = (n: number) => (s: string): boolean => s.length >= n
|
|
732
|
+
*
|
|
733
|
+
* // Create a refinement that checks for a string with a minimum length of 3
|
|
734
|
+
* const isLongString = Predicate.compose(isString, minLength(3))
|
|
735
|
+
*
|
|
736
|
+
* let value: unknown = "hello"
|
|
737
|
+
*
|
|
738
|
+
* assert.strictEqual(isLongString(value), true)
|
|
739
|
+
* if (isLongString(value)) {
|
|
740
|
+
* // value is narrowed to string
|
|
741
|
+
* assert.strictEqual(value.toUpperCase(), "HELLO")
|
|
742
|
+
* }
|
|
743
|
+
* assert.strictEqual(isLongString("hi"), false)
|
|
744
|
+
* ```
|
|
745
|
+
*
|
|
616
746
|
* @since 2.0.0
|
|
617
747
|
*/
|
|
618
748
|
exports.isRegExp = isRegExp;
|
|
619
749
|
const compose = exports.compose = /*#__PURE__*/(0, _Function.dual)(2, (ab, bc) => a => ab(a) && bc(a));
|
|
620
750
|
/**
|
|
751
|
+
* Combines two predicates to test a tuple of two values. The first predicate tests the
|
|
752
|
+
* first element of the tuple, and the second predicate tests the second element.
|
|
753
|
+
*
|
|
621
754
|
* @category combining
|
|
622
755
|
* @since 2.0.0
|
|
623
756
|
*/
|
|
624
757
|
const product = (self, that) => ([a, b]) => self(a) && that(b);
|
|
625
758
|
/**
|
|
759
|
+
* Takes an iterable of predicates and returns a new predicate that tests an array of values.
|
|
760
|
+
* The new predicate returns `true` if each predicate at a given index is satisfied by the
|
|
761
|
+
* value at the same index in the array. The check stops at the length of the shorter of
|
|
762
|
+
* the two iterables (predicates or values).
|
|
763
|
+
*
|
|
626
764
|
* @category combining
|
|
627
765
|
* @since 2.0.0
|
|
766
|
+
* @see tuple for a more powerful, variadic version.
|
|
628
767
|
*/
|
|
629
768
|
exports.product = product;
|
|
630
769
|
const all = collection => {
|
|
@@ -643,6 +782,9 @@ const all = collection => {
|
|
|
643
782
|
};
|
|
644
783
|
};
|
|
645
784
|
/**
|
|
785
|
+
* Combines a predicate for a single value and an iterable of predicates for the rest of an array.
|
|
786
|
+
* Useful for checking the head and tail of an array separately.
|
|
787
|
+
*
|
|
646
788
|
* @category combining
|
|
647
789
|
* @since 2.0.0
|
|
648
790
|
*/
|
|
@@ -652,12 +794,33 @@ const productMany = (self, collection) => {
|
|
|
652
794
|
return ([head, ...tail]) => self(head) === false ? false : rest(tail);
|
|
653
795
|
};
|
|
654
796
|
/**
|
|
655
|
-
*
|
|
797
|
+
* Combines an array of predicates into a single predicate that tests an array of values.
|
|
798
|
+
* This function is highly type-aware and will produce a `Refinement` if any of the provided
|
|
799
|
+
* predicates are `Refinement`s, allowing for powerful type-narrowing of tuples.
|
|
800
|
+
*
|
|
801
|
+
* - If all predicates are `Predicate<T>`, the result is `Predicate<[T, T, ...]>`.
|
|
802
|
+
* - If any predicate is a `Refinement<A, B>`, the result is a `Refinement` that narrows
|
|
803
|
+
* the input tuple type to a more specific tuple type.
|
|
656
804
|
*
|
|
657
|
-
*
|
|
658
|
-
*
|
|
659
|
-
*
|
|
660
|
-
*
|
|
805
|
+
* @example
|
|
806
|
+
* ```ts
|
|
807
|
+
* import * as assert from "node:assert"
|
|
808
|
+
* import { Predicate } from "effect"
|
|
809
|
+
*
|
|
810
|
+
* const isString = (u: unknown): u is string => typeof u === "string"
|
|
811
|
+
* const isNumber = (u: unknown): u is number => typeof u === "number"
|
|
812
|
+
*
|
|
813
|
+
* // Create a refinement for a [string, number] tuple
|
|
814
|
+
* const isStringNumberTuple = Predicate.tuple(isString, isNumber)
|
|
815
|
+
*
|
|
816
|
+
* const value: [unknown, unknown] = ["hello", 123]
|
|
817
|
+
* if (isStringNumberTuple(value)) {
|
|
818
|
+
* // value is narrowed to [string, number]
|
|
819
|
+
* const [s, n] = value
|
|
820
|
+
* assert.strictEqual(s.toUpperCase(), "HELLO")
|
|
821
|
+
* assert.strictEqual(n.toFixed(2), "123.00")
|
|
822
|
+
* }
|
|
823
|
+
* assert.strictEqual(isStringNumberTuple(["hello", "123"]), false)
|
|
661
824
|
* ```
|
|
662
825
|
*
|
|
663
826
|
* @since 2.0.0
|
|
@@ -665,10 +828,34 @@ const productMany = (self, collection) => {
|
|
|
665
828
|
exports.productMany = productMany;
|
|
666
829
|
const tuple = (...elements) => all(elements);
|
|
667
830
|
/**
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
831
|
+
* Combines a record of predicates into a single predicate that tests a record of values.
|
|
832
|
+
* This function is highly type-aware and will produce a `Refinement` if any of the provided
|
|
833
|
+
* predicates are `Refinement`s, allowing for powerful type-narrowing of structs.
|
|
834
|
+
*
|
|
835
|
+
* - If all predicates are `Predicate<T>`, the result is `Predicate<{ k: T, ... }>`.
|
|
836
|
+
* - If any predicate is a `Refinement<A, B>`, the result is a `Refinement` that narrows
|
|
837
|
+
* the input record type to a more specific record type.
|
|
838
|
+
*
|
|
839
|
+
* @example
|
|
840
|
+
* ```ts
|
|
841
|
+
* import * as assert from "node:assert"
|
|
842
|
+
* import { Predicate } from "effect"
|
|
843
|
+
*
|
|
844
|
+
* const isString = (u: unknown): u is string => typeof u === "string"
|
|
845
|
+
* const isNumber = (u: unknown): u is number => typeof u === "number"
|
|
846
|
+
*
|
|
847
|
+
* const personPredicate = Predicate.struct({
|
|
848
|
+
* name: isString,
|
|
849
|
+
* age: isNumber
|
|
850
|
+
* })
|
|
851
|
+
*
|
|
852
|
+
* const value: { name: unknown; age: unknown } = { name: "Alice", age: 30 }
|
|
853
|
+
* if (personPredicate(value)) {
|
|
854
|
+
* // value is narrowed to { name: string; age: number }
|
|
855
|
+
* assert.strictEqual(value.name.toUpperCase(), "ALICE")
|
|
856
|
+
* assert.strictEqual(value.age.toFixed(0), "30")
|
|
857
|
+
* }
|
|
858
|
+
* assert.strictEqual(personPredicate({ name: "Bob", age: "40" }), false)
|
|
672
859
|
* ```
|
|
673
860
|
*
|
|
674
861
|
* @since 2.0.0
|
|
@@ -686,18 +873,21 @@ const struct = fields => {
|
|
|
686
873
|
};
|
|
687
874
|
};
|
|
688
875
|
/**
|
|
689
|
-
*
|
|
876
|
+
* Returns a new predicate that is the logical negation of the given predicate.
|
|
877
|
+
*
|
|
878
|
+
* **Note**: If the input is a `Refinement`, the resulting predicate will be a
|
|
879
|
+
* simple `Predicate`, as TypeScript cannot infer the negative type.
|
|
690
880
|
*
|
|
691
881
|
* @example
|
|
692
882
|
* ```ts
|
|
693
883
|
* import * as assert from "node:assert"
|
|
694
884
|
* import { Predicate, Number } from "effect"
|
|
695
885
|
*
|
|
696
|
-
* const
|
|
886
|
+
* const isNonPositive = Predicate.not(Number.greaterThan(0))
|
|
697
887
|
*
|
|
698
|
-
* assert.
|
|
699
|
-
* assert.
|
|
700
|
-
* assert.
|
|
888
|
+
* assert.strictEqual(isNonPositive(-1), true)
|
|
889
|
+
* assert.strictEqual(isNonPositive(0), true)
|
|
890
|
+
* assert.strictEqual(isNonPositive(1), false)
|
|
701
891
|
* ```
|
|
702
892
|
*
|
|
703
893
|
* @category combinators
|
|
@@ -706,18 +896,31 @@ const struct = fields => {
|
|
|
706
896
|
exports.struct = struct;
|
|
707
897
|
const not = self => a => !self(a);
|
|
708
898
|
/**
|
|
709
|
-
* Combines two predicates
|
|
899
|
+
* Combines two predicates with a logical "OR". The resulting predicate returns `true`
|
|
900
|
+
* if at least one of the predicates returns `true`.
|
|
901
|
+
*
|
|
902
|
+
* If both predicates are `Refinement`s, the resulting predicate is a `Refinement` to the
|
|
903
|
+
* union of their target types (`B | C`).
|
|
710
904
|
*
|
|
711
905
|
* @example
|
|
712
906
|
* ```ts
|
|
713
907
|
* import * as assert from "node:assert"
|
|
714
|
-
* import { Predicate
|
|
908
|
+
* import { Predicate } from "effect"
|
|
909
|
+
*
|
|
910
|
+
* const isString = (u: unknown): u is string => typeof u === "string"
|
|
911
|
+
* const isNumber = (u: unknown): u is number => typeof u === "number"
|
|
912
|
+
*
|
|
913
|
+
* const isStringOrNumber = Predicate.or(isString, isNumber)
|
|
715
914
|
*
|
|
716
|
-
*
|
|
915
|
+
* assert.strictEqual(isStringOrNumber("hello"), true)
|
|
916
|
+
* assert.strictEqual(isStringOrNumber(123), true)
|
|
917
|
+
* assert.strictEqual(isStringOrNumber(null), false)
|
|
717
918
|
*
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
919
|
+
* const value: unknown = "world"
|
|
920
|
+
* if (isStringOrNumber(value)) {
|
|
921
|
+
* // value is narrowed to string | number
|
|
922
|
+
* console.log(value)
|
|
923
|
+
* }
|
|
721
924
|
* ```
|
|
722
925
|
*
|
|
723
926
|
* @category combinators
|
|
@@ -726,21 +929,34 @@ const not = self => a => !self(a);
|
|
|
726
929
|
exports.not = not;
|
|
727
930
|
const or = exports.or = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a => self(a) || that(a));
|
|
728
931
|
/**
|
|
729
|
-
* Combines two predicates
|
|
932
|
+
* Combines two predicates with a logical "AND". The resulting predicate returns `true`
|
|
933
|
+
* only if both of the predicates return `true`.
|
|
934
|
+
*
|
|
935
|
+
* If both predicates are `Refinement`s, the resulting predicate is a `Refinement` to the
|
|
936
|
+
* intersection of their target types (`B & C`).
|
|
730
937
|
*
|
|
731
938
|
* @example
|
|
732
939
|
* ```ts
|
|
733
940
|
* import * as assert from "node:assert"
|
|
734
941
|
* import { Predicate } from "effect"
|
|
735
942
|
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
943
|
+
* type Person = { name: string }
|
|
944
|
+
* type Employee = { id: number }
|
|
738
945
|
*
|
|
739
|
-
* const
|
|
946
|
+
* const hasName = (u: unknown): u is Person => Predicate.hasProperty(u, "name") && typeof (u as any).name === "string"
|
|
947
|
+
* const hasId = (u: unknown): u is Employee => Predicate.hasProperty(u, "id") && typeof (u as any).id === "number"
|
|
740
948
|
*
|
|
741
|
-
*
|
|
742
|
-
*
|
|
743
|
-
*
|
|
949
|
+
* const isPersonAndEmployee = Predicate.and(hasName, hasId)
|
|
950
|
+
*
|
|
951
|
+
* const val: unknown = { name: "Alice", id: 123 }
|
|
952
|
+
* if (isPersonAndEmployee(val)) {
|
|
953
|
+
* // val is narrowed to Person & Employee
|
|
954
|
+
* assert.strictEqual(val.name, "Alice")
|
|
955
|
+
* assert.strictEqual(val.id, 123)
|
|
956
|
+
* }
|
|
957
|
+
*
|
|
958
|
+
* assert.strictEqual(isPersonAndEmployee({ name: "Bob" }), false) // Missing id
|
|
959
|
+
* assert.strictEqual(isPersonAndEmployee({ id: 456 }), false) // Missing name
|
|
744
960
|
* ```
|
|
745
961
|
*
|
|
746
962
|
* @category combinators
|
|
@@ -748,57 +964,107 @@ const or = exports.or = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a =>
|
|
|
748
964
|
*/
|
|
749
965
|
const and = exports.and = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a => self(a) && that(a));
|
|
750
966
|
/**
|
|
967
|
+
* Combines two predicates with a logical "XOR" (exclusive OR). The resulting predicate
|
|
968
|
+
* returns `true` if one of the predicates returns `true`, but not both.
|
|
969
|
+
*
|
|
970
|
+
* @example
|
|
971
|
+
* ```ts
|
|
972
|
+
* import * as assert from "node:assert"
|
|
973
|
+
* import { Predicate } from "effect"
|
|
974
|
+
*
|
|
975
|
+
* const isPositive = (n: number) => n > 0
|
|
976
|
+
* const isEven = (n: number) => n % 2 === 0
|
|
977
|
+
*
|
|
978
|
+
* const isPositiveXorEven = Predicate.xor(isPositive, isEven)
|
|
979
|
+
*
|
|
980
|
+
* assert.strictEqual(isPositiveXorEven(4), false) // both true -> false
|
|
981
|
+
* assert.strictEqual(isPositiveXorEven(3), true) // one true -> true
|
|
982
|
+
* assert.strictEqual(isPositiveXorEven(-2), true) // one true -> true
|
|
983
|
+
* assert.strictEqual(isPositiveXorEven(-1), false) // both false -> false
|
|
984
|
+
* ```
|
|
985
|
+
*
|
|
751
986
|
* @category combinators
|
|
752
987
|
* @since 2.0.0
|
|
753
988
|
*/
|
|
754
989
|
const xor = exports.xor = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a => self(a) !== that(a));
|
|
755
990
|
/**
|
|
991
|
+
* Combines two predicates with a logical "EQV" (equivalence). The resulting predicate
|
|
992
|
+
* returns `true` if both predicates return the same boolean value (both `true` or both `false`).
|
|
993
|
+
*
|
|
994
|
+
* @example
|
|
995
|
+
* ```ts
|
|
996
|
+
* import * as assert from "node:assert"
|
|
997
|
+
* import { Predicate } from "effect"
|
|
998
|
+
*
|
|
999
|
+
* const isPositive = (n: number) => n > 0
|
|
1000
|
+
* const isEven = (n: number) => n % 2 === 0
|
|
1001
|
+
*
|
|
1002
|
+
* const isPositiveEqvEven = Predicate.eqv(isPositive, isEven)
|
|
1003
|
+
*
|
|
1004
|
+
* assert.strictEqual(isPositiveEqvEven(4), true) // both true -> true
|
|
1005
|
+
* assert.strictEqual(isPositiveEqvEven(3), false) // different -> false
|
|
1006
|
+
* assert.strictEqual(isPositiveEqvEven(-2), false) // different -> false
|
|
1007
|
+
* assert.strictEqual(isPositiveEqvEven(-1), true) // both false -> true
|
|
1008
|
+
* ```
|
|
1009
|
+
*
|
|
756
1010
|
* @category combinators
|
|
757
1011
|
* @since 2.0.0
|
|
758
1012
|
*/
|
|
759
1013
|
const eqv = exports.eqv = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a => self(a) === that(a));
|
|
760
1014
|
/**
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
* true. In simpler terms, `p implies q` can be interpreted as "if p then q". If
|
|
765
|
-
* the first predicate holds, then the second predicate must hold
|
|
766
|
-
* for the given context.
|
|
1015
|
+
* Creates a predicate that represents a logical "if-then" rule.
|
|
1016
|
+
*
|
|
1017
|
+
* Think of it as a conditional promise: **"If `antecedent` holds true, then I promise `consequent` will also be true."**
|
|
767
1018
|
*
|
|
768
|
-
*
|
|
1019
|
+
* This function is invaluable for defining complex validation logic where one condition dictates another.
|
|
769
1020
|
*
|
|
770
|
-
*
|
|
771
|
-
* because the outcome of the consequent cannot be determined.
|
|
1021
|
+
* ### How It Works
|
|
772
1022
|
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
* It proves especially helpful in defining property tests.
|
|
1023
|
+
* The rule only fails (returns `false`) when the "if" part is `true`, but the "then" part is `false`.
|
|
1024
|
+
* In all other cases, the promise is considered kept, and the result is `true`.
|
|
776
1025
|
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
1026
|
+
* This includes the concept of **"vacuous truth"**: if the "if" part is `false`, the rule doesn't apply,
|
|
1027
|
+
* so the promise isn't broken, and the result is `true`. (e.g., "If it rains, I'll bring an umbrella."
|
|
1028
|
+
* If it doesn't rain, you haven't broken your promise, no matter what).
|
|
1029
|
+
*
|
|
1030
|
+
* ### Key Details
|
|
1031
|
+
*
|
|
1032
|
+
* - **Logical Equivalence**: `implies(p, q)` is the same as `not(p).or(q)`, or simply `!p || q`
|
|
1033
|
+
* in plain JavaScript. This can be a helpful way to reason about its behavior.
|
|
1034
|
+
*
|
|
1035
|
+
* - **Type-Safety Warning**: This function always returns a `Predicate`, never a type-narrowing
|
|
1036
|
+
* `Refinement`. A `true` result doesn't guarantee the `consequent` passed (it could be `true`
|
|
1037
|
+
* simply because the `antecedent` was `false`), so it cannot be used to safely narrow a type.
|
|
780
1038
|
*
|
|
781
1039
|
* @example
|
|
782
1040
|
* ```ts
|
|
1041
|
+
* // Rule: A user can only be an admin if they also belong to the "staff" group.
|
|
783
1042
|
* import * as assert from "node:assert"
|
|
784
1043
|
* import { Predicate } from "effect"
|
|
785
1044
|
*
|
|
786
|
-
* type
|
|
787
|
-
*
|
|
788
|
-
*
|
|
789
|
-
* readonly c: number
|
|
1045
|
+
* type User = {
|
|
1046
|
+
* isStaff: boolean
|
|
1047
|
+
* isAdmin: boolean
|
|
790
1048
|
* }
|
|
791
1049
|
*
|
|
792
|
-
* const
|
|
793
|
-
* // antecedent
|
|
794
|
-
* (
|
|
795
|
-
* // consequent
|
|
796
|
-
* (
|
|
1050
|
+
* const isValidUserPermission = Predicate.implies(
|
|
1051
|
+
* // antecedent: "if" the user is an admin...
|
|
1052
|
+
* (user: User) => user.isAdmin,
|
|
1053
|
+
* // consequent: "then" they must be staff.
|
|
1054
|
+
* (user: User) => user.isStaff
|
|
797
1055
|
* )
|
|
798
1056
|
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
1057
|
+
* // A non-admin who is not staff. Rule doesn't apply (antecedent is false).
|
|
1058
|
+
* assert.strictEqual(isValidUserPermission({ isStaff: false, isAdmin: false }), true)
|
|
1059
|
+
*
|
|
1060
|
+
* // A staff member who is not an admin. Rule doesn't apply (antecedent is false).
|
|
1061
|
+
* assert.strictEqual(isValidUserPermission({ isStaff: true, isAdmin: false }), true)
|
|
1062
|
+
*
|
|
1063
|
+
* // An admin who is also staff. The rule was followed.
|
|
1064
|
+
* assert.strictEqual(isValidUserPermission({ isStaff: true, isAdmin: true }), true)
|
|
1065
|
+
*
|
|
1066
|
+
* // An admin who is NOT staff. The rule was broken!
|
|
1067
|
+
* assert.strictEqual(isValidUserPermission({ isStaff: false, isAdmin: true }), false)
|
|
802
1068
|
* ```
|
|
803
1069
|
*
|
|
804
1070
|
* @category combinators
|
|
@@ -806,18 +1072,47 @@ const eqv = exports.eqv = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a
|
|
|
806
1072
|
*/
|
|
807
1073
|
const implies = exports.implies = /*#__PURE__*/(0, _Function.dual)(2, (antecedent, consequent) => a => antecedent(a) ? consequent(a) : true);
|
|
808
1074
|
/**
|
|
1075
|
+
* Combines two predicates with a logical "NOR" (negated OR). The resulting predicate
|
|
1076
|
+
* returns `true` only if both predicates return `false`.
|
|
1077
|
+
* This is equivalent to `not(or(p, q))`.
|
|
1078
|
+
*
|
|
809
1079
|
* @category combinators
|
|
810
1080
|
* @since 2.0.0
|
|
811
1081
|
*/
|
|
812
1082
|
const nor = exports.nor = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a => !(self(a) || that(a)));
|
|
813
1083
|
/**
|
|
1084
|
+
* Combines two predicates with a logical "NAND" (negated AND). The resulting predicate
|
|
1085
|
+
* returns `true` if at least one of the predicates returns `false`.
|
|
1086
|
+
* This is equivalent to `not(and(p, q))`.
|
|
1087
|
+
*
|
|
814
1088
|
* @category combinators
|
|
815
1089
|
* @since 2.0.0
|
|
816
1090
|
*/
|
|
817
1091
|
const nand = exports.nand = /*#__PURE__*/(0, _Function.dual)(2, (self, that) => a => !(self(a) && that(a)));
|
|
818
1092
|
/**
|
|
1093
|
+
* Takes an iterable of predicates and returns a new predicate. The new predicate
|
|
1094
|
+
* returns `true` if all predicates in the collection return `true` for a given value.
|
|
1095
|
+
*
|
|
1096
|
+
* This is like `Array.prototype.every` but for a collection of predicates.
|
|
1097
|
+
*
|
|
1098
|
+
* @example
|
|
1099
|
+
* ```ts
|
|
1100
|
+
* import * as assert from "node:assert"
|
|
1101
|
+
* import { Predicate } from "effect"
|
|
1102
|
+
*
|
|
1103
|
+
* const isPositive = (n: number) => n > 0
|
|
1104
|
+
* const isEven = (n: number) => n % 2 === 0
|
|
1105
|
+
*
|
|
1106
|
+
* const isPositiveAndEven = Predicate.every([isPositive, isEven])
|
|
1107
|
+
*
|
|
1108
|
+
* assert.strictEqual(isPositiveAndEven(4), true)
|
|
1109
|
+
* assert.strictEqual(isPositiveAndEven(3), false)
|
|
1110
|
+
* assert.strictEqual(isPositiveAndEven(-2), false)
|
|
1111
|
+
* ```
|
|
1112
|
+
*
|
|
819
1113
|
* @category elements
|
|
820
1114
|
* @since 2.0.0
|
|
1115
|
+
* @see some
|
|
821
1116
|
*/
|
|
822
1117
|
const every = collection => a => {
|
|
823
1118
|
for (const p of collection) {
|
|
@@ -828,8 +1123,29 @@ const every = collection => a => {
|
|
|
828
1123
|
return true;
|
|
829
1124
|
};
|
|
830
1125
|
/**
|
|
1126
|
+
* Takes an iterable of predicates and returns a new predicate. The new predicate
|
|
1127
|
+
* returns `true` if at least one predicate in the collection returns `true` for a given value.
|
|
1128
|
+
*
|
|
1129
|
+
* This is like `Array.prototype.some` but for a collection of predicates.
|
|
1130
|
+
*
|
|
1131
|
+
* @example
|
|
1132
|
+
* ```ts
|
|
1133
|
+
* import * as assert from "node:assert"
|
|
1134
|
+
* import { Predicate } from "effect"
|
|
1135
|
+
*
|
|
1136
|
+
* const isNegative = (n: number) => n < 0
|
|
1137
|
+
* const isOdd = (n: number) => n % 2 !== 0
|
|
1138
|
+
*
|
|
1139
|
+
* const isNegativeOrOdd = Predicate.some([isNegative, isOdd])
|
|
1140
|
+
*
|
|
1141
|
+
* assert.strictEqual(isNegativeOrOdd(-2), true) // isNegative is true
|
|
1142
|
+
* assert.strictEqual(isNegativeOrOdd(3), true) // isOdd is true
|
|
1143
|
+
* assert.strictEqual(isNegativeOrOdd(4), false) // both are false
|
|
1144
|
+
* ```
|
|
1145
|
+
*
|
|
831
1146
|
* @category elements
|
|
832
1147
|
* @since 2.0.0
|
|
1148
|
+
* @see every
|
|
833
1149
|
*/
|
|
834
1150
|
exports.every = every;
|
|
835
1151
|
const some = collection => a => {
|