@statedelta-libs/operators 0.0.1

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.
@@ -0,0 +1,2353 @@
1
+ /**
2
+ * Returns its argument unchanged.
3
+ *
4
+ * The identity function is useful as a default transformation,
5
+ * placeholder in pipelines, or when a function is required but
6
+ * no transformation is needed.
7
+ *
8
+ * @param x - The value to return
9
+ * @returns The same value
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * identity(5); // 5
14
+ * identity({ a: 1 }); // { a: 1 }
15
+ * identity([1, 2, 3]); // [1, 2, 3]
16
+ *
17
+ * // Useful as default in pipelines
18
+ * const transform = condition ? someTransform : identity;
19
+ * pipe(data, transform, process);
20
+ *
21
+ * // Useful as filter predicate (keeps truthy values)
22
+ * [1, 0, 2, null, 3].filter(identity); // [1, 2, 3]
23
+ * ```
24
+ */
25
+ declare function identity<T>(x: T): T;
26
+
27
+ /**
28
+ * Creates a function that always returns the same value.
29
+ *
30
+ * Useful for providing constant values in places that expect functions,
31
+ * like in `cond`, `ifElse`, or as default transformations.
32
+ *
33
+ * @param x - The value to always return
34
+ * @returns A function that ignores its arguments and returns x
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * const alwaysFive = always(5);
39
+ * alwaysFive(); // 5
40
+ * alwaysFive(100); // 5
41
+ * alwaysFive('any'); // 5
42
+ *
43
+ * // Useful in conditionals
44
+ * const getDiscount = cond([
45
+ * [propEq('tier', 'gold'), always(0.3)],
46
+ * [propEq('tier', 'silver'), always(0.2)],
47
+ * [T, always(0)] // default
48
+ * ]);
49
+ *
50
+ * // Useful in ifElse
51
+ * const discount = ifElse(
52
+ * propEq('vip', true),
53
+ * always(0.2),
54
+ * always(0)
55
+ * );
56
+ * ```
57
+ */
58
+ declare function always<T>(x: T): () => T;
59
+
60
+ /**
61
+ * Constant functions that return true or false.
62
+ *
63
+ * These are useful as default predicates in conditional functions
64
+ * like `cond`, `filter`, or as terminal cases in pattern matching.
65
+ */
66
+ /**
67
+ * A function that always returns true.
68
+ *
69
+ * Useful as a default case or catch-all predicate.
70
+ *
71
+ * @returns Always true
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * T(); // true
76
+ *
77
+ * // Default case in cond
78
+ * const classify = cond([
79
+ * [propEq('type', 'admin'), always('full')],
80
+ * [propEq('type', 'user'), always('limited')],
81
+ * [T, always('none')] // default case - always matches
82
+ * ]);
83
+ *
84
+ * // Always include
85
+ * filter(T, [1, 2, 3]); // [1, 2, 3]
86
+ * ```
87
+ */
88
+ declare function T$1(): true;
89
+ /**
90
+ * A function that always returns false.
91
+ *
92
+ * Useful as a never-matching predicate or to explicitly exclude.
93
+ *
94
+ * @returns Always false
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * F(); // false
99
+ *
100
+ * // Never match
101
+ * filter(F, [1, 2, 3]); // []
102
+ *
103
+ * // Explicit disable
104
+ * const shouldProcess = isEnabled ? checkCondition : F;
105
+ * ```
106
+ */
107
+ declare function F(): false;
108
+
109
+ /**
110
+ * Executes a side-effect function and returns the original value.
111
+ *
112
+ * `tap` is invaluable for debugging pipelines, logging intermediate
113
+ * values, or performing side-effects without breaking the data flow.
114
+ * The side-effect function's return value is ignored.
115
+ *
116
+ * @param fn - The side-effect function to execute
117
+ * @param x - The value to pass through
118
+ * @returns The original value x, unchanged
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * // Debugging a pipeline
123
+ * pipe(
124
+ * [1, 2, 3, 4, 5],
125
+ * filter(x => x > 2),
126
+ * tap(console.log), // logs: [3, 4, 5]
127
+ * map(x => x * 2),
128
+ * tap(console.log), // logs: [6, 8, 10]
129
+ * sum
130
+ * ); // 24
131
+ *
132
+ * // Curried usage
133
+ * const log = tap(console.log);
134
+ * log('hello'); // logs 'hello', returns 'hello'
135
+ *
136
+ * // Side-effects in transformations
137
+ * const users = pipe(
138
+ * fetchUsers(),
139
+ * tap(users => analytics.track('users_fetched', { count: users.length })),
140
+ * filter(user => user.active)
141
+ * );
142
+ * ```
143
+ */
144
+ interface TapFn {
145
+ <T>(fn: (x: T) => void, x: T): T;
146
+ <T>(fn: (x: T) => void): (x: T) => T;
147
+ }
148
+ declare const tap: TapFn;
149
+
150
+ /**
151
+ * @statedelta-libs/operators - Type Definitions
152
+ *
153
+ * Core type definitions for the functional operators library.
154
+ */
155
+ /**
156
+ * Unique symbol used to identify placeholder values in curried functions.
157
+ * Allows "skipping" arguments when partially applying functions.
158
+ */
159
+ declare const PLACEHOLDER: unique symbol;
160
+ /**
161
+ * The Placeholder type represents the `__` value used in curried functions.
162
+ */
163
+ type Placeholder = typeof PLACEHOLDER & {
164
+ readonly __: unique symbol;
165
+ };
166
+ /**
167
+ * Generic function type with any number of arguments.
168
+ */
169
+ type Fn<Args extends unknown[] = unknown[], R = unknown> = (...args: Args) => R;
170
+ /**
171
+ * Unary function - takes exactly one argument.
172
+ */
173
+ type UnaryFn<A, R> = (a: A) => R;
174
+ /**
175
+ * Generic unary function type that accepts any function.
176
+ * Uses `any` following Ramda's approach - TypeScript cannot precisely
177
+ * infer types for arbitrary function composition.
178
+ */
179
+ type AnyUnaryFn = (arg: any) => any;
180
+ /**
181
+ * Binary function - takes exactly two arguments.
182
+ */
183
+ type BinaryFn<A, B, R> = (a: A, b: B) => R;
184
+ /**
185
+ * Ternary function - takes exactly three arguments.
186
+ */
187
+ type TernaryFn<A, B, C, R> = (a: A, b: B, c: C) => R;
188
+ /**
189
+ * Variadic function - takes any number of arguments.
190
+ */
191
+ type VariadicFn<R = unknown> = (...args: unknown[]) => R;
192
+ /**
193
+ * Curried unary function.
194
+ * Can be called with no args (returns itself) or one arg (returns result).
195
+ */
196
+ interface Curry1<A, R> {
197
+ (): Curry1<A, R>;
198
+ (a: A): R;
199
+ }
200
+ /**
201
+ * Curried binary function with placeholder support.
202
+ */
203
+ interface Curry2<A, B, R> {
204
+ (): Curry2<A, B, R>;
205
+ (a: A): Curry1<B, R>;
206
+ (a: Placeholder): Curry2<A, B, R>;
207
+ (a: A, b: B): R;
208
+ (a: A, b: Placeholder): Curry1<B, R>;
209
+ (a: Placeholder, b: B): Curry1<A, R>;
210
+ (a: Placeholder, b: Placeholder): Curry2<A, B, R>;
211
+ }
212
+ /**
213
+ * Curried ternary function with placeholder support.
214
+ */
215
+ interface Curry3<A, B, C, R> {
216
+ (): Curry3<A, B, C, R>;
217
+ (a: A): Curry2<B, C, R>;
218
+ (a: Placeholder): Curry3<A, B, C, R>;
219
+ (a: A, b: B): Curry1<C, R>;
220
+ (a: A, b: Placeholder): Curry2<B, C, R>;
221
+ (a: Placeholder, b: B): Curry2<A, C, R>;
222
+ (a: A, b: B, c: C): R;
223
+ (a: A, b: B, c: Placeholder): Curry1<C, R>;
224
+ (a: A, b: Placeholder, c: C): Curry1<B, R>;
225
+ (a: Placeholder, b: B, c: C): Curry1<A, R>;
226
+ (a: A, b: Placeholder, c: Placeholder): Curry2<B, C, R>;
227
+ (a: Placeholder, b: B, c: Placeholder): Curry2<A, C, R>;
228
+ (a: Placeholder, b: Placeholder, c: C): Curry2<A, B, R>;
229
+ (a: Placeholder, b: Placeholder, c: Placeholder): Curry3<A, B, C, R>;
230
+ }
231
+ /**
232
+ * Curried quaternary function with placeholder support.
233
+ */
234
+ interface Curry4<A, B, C, D, R> {
235
+ (): Curry4<A, B, C, D, R>;
236
+ (a: A): Curry3<B, C, D, R>;
237
+ (a: Placeholder): Curry4<A, B, C, D, R>;
238
+ (a: A, b: B): Curry2<C, D, R>;
239
+ (a: A, b: Placeholder): Curry3<B, C, D, R>;
240
+ (a: Placeholder, b: B): Curry3<A, C, D, R>;
241
+ (a: A, b: B, c: C): Curry1<D, R>;
242
+ (a: A, b: B, c: Placeholder): Curry2<C, D, R>;
243
+ (a: A, b: Placeholder, c: C): Curry2<B, D, R>;
244
+ (a: Placeholder, b: B, c: C): Curry2<A, D, R>;
245
+ (a: A, b: B, c: C, d: D): R;
246
+ (a: A, b: B, c: C, d: Placeholder): Curry1<D, R>;
247
+ (a: A, b: B, c: Placeholder, d: D): Curry1<C, R>;
248
+ (a: A, b: Placeholder, c: C, d: D): Curry1<B, R>;
249
+ (a: Placeholder, b: B, c: C, d: D): Curry1<A, R>;
250
+ (a: A, b: Placeholder, c: Placeholder, d: D): Curry2<B, C, R>;
251
+ (a: Placeholder, b: B, c: Placeholder, d: D): Curry2<A, C, R>;
252
+ (a: Placeholder, b: Placeholder, c: C, d: D): Curry2<A, B, R>;
253
+ (a: A, b: B, c: Placeholder, d: Placeholder): Curry2<C, D, R>;
254
+ (a: A, b: Placeholder, c: C, d: Placeholder): Curry2<B, D, R>;
255
+ (a: Placeholder, b: B, c: C, d: Placeholder): Curry2<A, D, R>;
256
+ (a: Placeholder, b: Placeholder, c: Placeholder, d: D): Curry3<A, B, C, R>;
257
+ (a: Placeholder, b: Placeholder, c: C, d: Placeholder): Curry3<A, B, D, R>;
258
+ (a: Placeholder, b: B, c: Placeholder, d: Placeholder): Curry3<A, C, D, R>;
259
+ (a: A, b: Placeholder, c: Placeholder, d: Placeholder): Curry3<B, C, D, R>;
260
+ }
261
+ /**
262
+ * Extract the first element type of a tuple.
263
+ */
264
+ type Head<T extends unknown[]> = T extends [infer H, ...unknown[]] ? H : never;
265
+ /**
266
+ * Extract all but the first element of a tuple.
267
+ */
268
+ type Tail<T extends unknown[]> = T extends [unknown, ...infer R] ? R : never;
269
+ /**
270
+ * Extract the last element type of a tuple.
271
+ */
272
+ type Last<T extends unknown[]> = T extends [...unknown[], infer L] ? L : never;
273
+ /**
274
+ * Pipe function overloads for type inference.
275
+ */
276
+ interface PipeFn {
277
+ <A>(a: A): A;
278
+ <A, B>(a: A, ab: UnaryFn<A, B>): B;
279
+ <A, B, C>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>): C;
280
+ <A, B, C, D>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>): D;
281
+ <A, B, C, D, E>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>): E;
282
+ <A, B, C, D, E, F>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>): F;
283
+ <A, B, C, D, E, F, G>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>): G;
284
+ <A, B, C, D, E, F, G, H>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>, gh: UnaryFn<G, H>): H;
285
+ <A, B, C, D, E, F, G, H, I>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>, gh: UnaryFn<G, H>, hi: UnaryFn<H, I>): I;
286
+ <A, B, C, D, E, F, G, H, I, J>(a: A, ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>, gh: UnaryFn<G, H>, hi: UnaryFn<H, I>, ij: UnaryFn<I, J>): J;
287
+ (a: unknown, ...fns: AnyUnaryFn[]): unknown;
288
+ }
289
+ /**
290
+ * Pipe builder that returns a composed function.
291
+ */
292
+ interface PipeBuilderFn {
293
+ (): <T>(x: T) => T;
294
+ <A, B>(ab: UnaryFn<A, B>): UnaryFn<A, B>;
295
+ <A, B, C>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>): UnaryFn<A, C>;
296
+ <A, B, C, D>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>): UnaryFn<A, D>;
297
+ <A, B, C, D, E>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>): UnaryFn<A, E>;
298
+ <A, B, C, D, E, F>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>): UnaryFn<A, F>;
299
+ <A, B, C, D, E, F, G>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>): UnaryFn<A, G>;
300
+ <A, B, C, D, E, F, G, H>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>, gh: UnaryFn<G, H>): UnaryFn<A, H>;
301
+ <A, B, C, D, E, F, G, H, I>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>, gh: UnaryFn<G, H>, hi: UnaryFn<H, I>): UnaryFn<A, I>;
302
+ <A, B, C, D, E, F, G, H, I, J>(ab: UnaryFn<A, B>, bc: UnaryFn<B, C>, cd: UnaryFn<C, D>, de: UnaryFn<D, E>, ef: UnaryFn<E, F>, fg: UnaryFn<F, G>, gh: UnaryFn<G, H>, hi: UnaryFn<H, I>, ij: UnaryFn<I, J>): UnaryFn<A, J>;
303
+ (...fns: AnyUnaryFn[]): AnyUnaryFn;
304
+ }
305
+ /**
306
+ * Compose builder that returns a composed function (right to left).
307
+ */
308
+ interface ComposeBuilderFn {
309
+ (): <T>(x: T) => T;
310
+ <A, B>(ab: UnaryFn<A, B>): UnaryFn<A, B>;
311
+ <A, B, C>(bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, C>;
312
+ <A, B, C, D>(cd: UnaryFn<C, D>, bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, D>;
313
+ <A, B, C, D, E>(de: UnaryFn<D, E>, cd: UnaryFn<C, D>, bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, E>;
314
+ <A, B, C, D, E, F>(ef: UnaryFn<E, F>, de: UnaryFn<D, E>, cd: UnaryFn<C, D>, bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, F>;
315
+ <A, B, C, D, E, F, G>(fg: UnaryFn<F, G>, ef: UnaryFn<E, F>, de: UnaryFn<D, E>, cd: UnaryFn<C, D>, bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, G>;
316
+ <A, B, C, D, E, F, G, H>(gh: UnaryFn<G, H>, fg: UnaryFn<F, G>, ef: UnaryFn<E, F>, de: UnaryFn<D, E>, cd: UnaryFn<C, D>, bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, H>;
317
+ <A, B, C, D, E, F, G, H, I>(hi: UnaryFn<H, I>, gh: UnaryFn<G, H>, fg: UnaryFn<F, G>, ef: UnaryFn<E, F>, de: UnaryFn<D, E>, cd: UnaryFn<C, D>, bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, I>;
318
+ <A, B, C, D, E, F, G, H, I, J>(ij: UnaryFn<I, J>, hi: UnaryFn<H, I>, gh: UnaryFn<G, H>, fg: UnaryFn<F, G>, ef: UnaryFn<E, F>, de: UnaryFn<D, E>, cd: UnaryFn<C, D>, bc: UnaryFn<B, C>, ab: UnaryFn<A, B>): UnaryFn<A, J>;
319
+ (...fns: AnyUnaryFn[]): AnyUnaryFn;
320
+ }
321
+ /**
322
+ * Makes a type nullable (T | null | undefined).
323
+ */
324
+ type Nullable<T> = T | null | undefined;
325
+ /**
326
+ * Extracts the return type of a function.
327
+ */
328
+ type ReturnOf<F> = F extends (...args: unknown[]) => infer R ? R : never;
329
+ /**
330
+ * Extracts the parameter types of a function as a tuple.
331
+ */
332
+ type ParamsOf<F> = F extends (...args: infer P) => unknown ? P : never;
333
+ /**
334
+ * Deep readonly type.
335
+ */
336
+ type DeepReadonly<T> = T extends (...args: unknown[]) => unknown ? T : T extends object ? {
337
+ readonly [K in keyof T]: DeepReadonly<T[K]>;
338
+ } : T;
339
+ /**
340
+ * Predicate function - returns boolean.
341
+ */
342
+ type Predicate<T> = (value: T, index: number, array: readonly T[]) => boolean;
343
+ /**
344
+ * Mapper function - transforms value.
345
+ */
346
+ type Mapper<T, U> = (value: T, index: number, array: readonly T[]) => U;
347
+ /**
348
+ * Reducer function - accumulates value.
349
+ */
350
+ type Reducer<T, U> = (accumulator: U, value: T, index: number, array: readonly T[]) => U;
351
+ /**
352
+ * Comparator function - compares two values.
353
+ */
354
+ type Comparator<T> = (a: T, b: T) => number;
355
+
356
+ /**
357
+ * Transforms a function into a curried version.
358
+ *
359
+ * A curried function can be called with fewer arguments than it expects.
360
+ * It returns a new function that takes the remaining arguments.
361
+ * Supports placeholder (`__`) for skipping arguments.
362
+ *
363
+ * @param fn - The function to curry
364
+ * @returns A curried version of the function
365
+ *
366
+ * @example
367
+ * ```ts
368
+ * // Basic currying
369
+ * const add3 = curry((a: number, b: number, c: number) => a + b + c);
370
+ *
371
+ * add3(1, 2, 3); // 6
372
+ * add3(1)(2)(3); // 6
373
+ * add3(1, 2)(3); // 6
374
+ * add3(1)(2, 3); // 6
375
+ *
376
+ * // With placeholder
377
+ * const addTenToMiddle = add3(__, 10, __);
378
+ * addTenToMiddle(1, 2); // 13 (1 + 10 + 2)
379
+ *
380
+ * // Practical example
381
+ * const greet = curry((greeting: string, name: string) => `${greeting}, ${name}!`);
382
+ * const sayHello = greet('Hello');
383
+ * sayHello('World'); // 'Hello, World!'
384
+ * ```
385
+ */
386
+
387
+ /**
388
+ * Curries a function, using optimized implementations for common arities.
389
+ *
390
+ * @param fn - The function to curry
391
+ * @returns A curried version of the function
392
+ */
393
+ declare function curry<A, R>(fn: (a: A) => R): Curry1<A, R>;
394
+ declare function curry<A, B, R>(fn: (a: A, b: B) => R): Curry2<A, B, R>;
395
+ declare function curry<A, B, C, R>(fn: (a: A, b: B, c: C) => R): Curry3<A, B, C, R>;
396
+ declare function curry<A, B, C, D, R>(fn: (a: A, b: B, c: C, d: D) => R): Curry4<A, B, C, D, R>;
397
+
398
+ /**
399
+ * Curries a function with a specified arity.
400
+ *
401
+ * Unlike `curry`, which uses `fn.length` to determine arity,
402
+ * `curryN` allows explicit control. This is useful for:
403
+ * - Functions with default parameters (where `length` is misleading)
404
+ * - Variadic functions that should be curried to a specific arity
405
+ * - Functions with rest parameters
406
+ *
407
+ * @param arity - The number of arguments to curry
408
+ * @param fn - The function to curry
409
+ * @returns A curried version of the function
410
+ *
411
+ * @example
412
+ * ```ts
413
+ * // Function with default parameter
414
+ * const greet = (greeting: string, name: string, punctuation = '!') =>
415
+ * `${greeting}, ${name}${punctuation}`;
416
+ *
417
+ * // greet.length is 2 (doesn't count default param)
418
+ * // But we want to curry all 3 parameters
419
+ * const curriedGreet = curryN(3, greet);
420
+ *
421
+ * curriedGreet('Hello')('World')('?'); // 'Hello, World?'
422
+ * curriedGreet('Hello', 'World', '?'); // 'Hello, World?'
423
+ *
424
+ * // Variadic function curried to specific arity
425
+ * const sum = (...nums: number[]) => nums.reduce((a, b) => a + b, 0);
426
+ * const sum3 = curryN(3, sum);
427
+ *
428
+ * sum3(1)(2)(3); // 6
429
+ * sum3(1, 2)(3); // 6
430
+ * ```
431
+ */
432
+
433
+ /**
434
+ * Curries a function with explicit arity control.
435
+ */
436
+ declare function curryN<R>(arity: 0, fn: () => R): () => R;
437
+ declare function curryN<A, R>(arity: 1, fn: (a: A) => R): Curry1<A, R>;
438
+ declare function curryN<A, B, R>(arity: 2, fn: (a: A, b: B) => R): Curry2<A, B, R>;
439
+ declare function curryN<A, B, C, R>(arity: 3, fn: (a: A, b: B, c: C) => R): Curry3<A, B, C, R>;
440
+ declare function curryN<A, B, C, D, R>(arity: 4, fn: (a: A, b: B, c: C, d: D) => R): Curry4<A, B, C, D, R>;
441
+ declare function curryN<R>(arity: number, fn: (...args: any[]) => R): (...args: any[]) => any;
442
+
443
+ /**
444
+ * Partially applies a function by fixing some arguments.
445
+ *
446
+ * Unlike currying (which waits for one argument at a time),
447
+ * partial application immediately fixes multiple arguments.
448
+ * Supports placeholder (`__`) for skipping arguments.
449
+ *
450
+ * @param fn - The function to partially apply
451
+ * @param args - The arguments to fix (can include placeholders)
452
+ * @returns A function waiting for the remaining arguments
453
+ *
454
+ * @example
455
+ * ```ts
456
+ * const greet = (greeting: string, name: string, punctuation: string) =>
457
+ * `${greeting}, ${name}${punctuation}`;
458
+ *
459
+ * // Fix first argument
460
+ * const sayHello = partial(greet, ['Hello']);
461
+ * sayHello('World', '!'); // 'Hello, World!'
462
+ *
463
+ * // Fix multiple arguments
464
+ * const helloWorld = partial(greet, ['Hello', 'World']);
465
+ * helloWorld('!'); // 'Hello, World!'
466
+ *
467
+ * // With placeholders
468
+ * const askName = partial(greet, [__, __, '?']);
469
+ * askName('Hey', 'You'); // 'Hey, You?'
470
+ *
471
+ * const greetWorld = partial(greet, [__, 'World', '!']);
472
+ * greetWorld('Hi'); // 'Hi, World!'
473
+ * ```
474
+ */
475
+
476
+ /**
477
+ * Partially applies a function with the given arguments.
478
+ */
479
+ declare function partial<T extends (...args: never[]) => unknown>(fn: T, args: readonly (unknown | Placeholder)[]): (...remainingArgs: unknown[]) => ReturnType<T>;
480
+ /**
481
+ * Like partial, but applies arguments from the right.
482
+ *
483
+ * @param fn - The function to partially apply
484
+ * @param args - The arguments to fix from the right
485
+ * @returns A function waiting for the remaining arguments
486
+ *
487
+ * @example
488
+ * ```ts
489
+ * const greet = (greeting: string, name: string, punctuation: string) =>
490
+ * `${greeting}, ${name}${punctuation}`;
491
+ *
492
+ * // Fix last argument
493
+ * const exclaim = partialRight(greet, ['!']);
494
+ * exclaim('Hello', 'World'); // 'Hello, World!'
495
+ *
496
+ * // Fix last two arguments
497
+ * const greetWorldExclaim = partialRight(greet, ['World', '!']);
498
+ * greetWorldExclaim('Hello'); // 'Hello, World!'
499
+ * ```
500
+ */
501
+ declare function partialRight<T extends (...args: never[]) => unknown>(fn: T, args: readonly unknown[]): (...remainingArgs: unknown[]) => ReturnType<T>;
502
+
503
+ /**
504
+ * Performs left-to-right function composition.
505
+ *
506
+ * `pipe` takes a value and a sequence of functions, applying each
507
+ * function to the result of the previous one. This creates a clear,
508
+ * readable data transformation pipeline.
509
+ *
510
+ * For creating reusable composed functions, see `pipeWith` or use
511
+ * `pipe` with a leading function.
512
+ *
513
+ * @example
514
+ * ```ts
515
+ * // Direct application
516
+ * pipe(
517
+ * 5,
518
+ * x => x + 1, // 6
519
+ * x => x * 2, // 12
520
+ * x => `Result: ${x}` // 'Result: 12'
521
+ * );
522
+ *
523
+ * // With array operations
524
+ * pipe(
525
+ * [1, 2, 3, 4, 5],
526
+ * arr => arr.filter(x => x > 2),
527
+ * arr => arr.map(x => x * 2),
528
+ * arr => arr.reduce((a, b) => a + b, 0)
529
+ * ); // 24
530
+ *
531
+ * // Building pipelines
532
+ * const process = (data: number[]) => pipe(
533
+ * data,
534
+ * filter(x => x > 0),
535
+ * map(x => x * 2),
536
+ * sum
537
+ * );
538
+ * ```
539
+ */
540
+
541
+ /**
542
+ * Applies a sequence of functions to a value, left-to-right.
543
+ */
544
+ declare const pipe: PipeFn;
545
+ /**
546
+ * Creates a composed function from left-to-right.
547
+ *
548
+ * Unlike `pipe` which immediately applies to a value, `pipeBuilder`
549
+ * returns a reusable function.
550
+ *
551
+ * @example
552
+ * ```ts
553
+ * const process = pipeBuilder(
554
+ * (x: number) => x + 1,
555
+ * x => x * 2,
556
+ * x => `Result: ${x}`
557
+ * );
558
+ *
559
+ * process(5); // 'Result: 12'
560
+ * process(10); // 'Result: 22'
561
+ * ```
562
+ */
563
+ declare const pipeBuilder: PipeBuilderFn;
564
+
565
+ /**
566
+ * Performs right-to-left function composition.
567
+ *
568
+ * `compose` creates a function that applies its arguments from right
569
+ * to left. This matches mathematical function composition notation:
570
+ * compose(f, g, h)(x) === f(g(h(x)))
571
+ *
572
+ * Most developers find `pipe` (left-to-right) more intuitive for
573
+ * data processing pipelines, but `compose` is useful when you want
574
+ * to match mathematical notation or build functions "inside out".
575
+ *
576
+ * @example
577
+ * ```ts
578
+ * // Mathematical notation: (f ∘ g ∘ h)(x) = f(g(h(x)))
579
+ * const process = compose(
580
+ * (x: number) => `Result: ${x}`, // applied 3rd
581
+ * (x: number) => x * 2, // applied 2nd
582
+ * (x: number) => x + 1 // applied 1st
583
+ * );
584
+ *
585
+ * process(5); // 'Result: 12'
586
+ *
587
+ * // Equivalent to:
588
+ * // step1 = 5 + 1 = 6
589
+ * // step2 = 6 * 2 = 12
590
+ * // step3 = 'Result: 12'
591
+ *
592
+ * // Practical example
593
+ * const getFullName = compose(
594
+ * (s: string) => s.trim(),
595
+ * (parts: string[]) => parts.join(' '),
596
+ * (user: { first: string; last: string }) => [user.first, user.last]
597
+ * );
598
+ *
599
+ * getFullName({ first: 'John', last: 'Doe' }); // 'John Doe'
600
+ * ```
601
+ */
602
+
603
+ /**
604
+ * Creates a composed function from right-to-left.
605
+ */
606
+ declare const compose: ComposeBuilderFn;
607
+
608
+ /**
609
+ * Performs left-to-right function composition with a transformer.
610
+ *
611
+ * `pipeWith` is like `pipe`, but applies a transformer function between
612
+ * each step. This is useful for:
613
+ * - Logging/debugging pipelines
614
+ * - Handling async operations (Promise resolution)
615
+ * - Validation between steps
616
+ * - Performance monitoring
617
+ *
618
+ * The transformer receives the next function and the current value,
619
+ * and should return the result to pass to the next step.
620
+ *
621
+ * @param transformer - Function called between each step: (fn, value) => result
622
+ * @param fns - The functions to compose
623
+ * @returns A composed function
624
+ *
625
+ * @example
626
+ * ```ts
627
+ * // Logging transformer
628
+ * const loggedPipe = pipeWith(
629
+ * (fn, val) => {
630
+ * console.log('Input:', val);
631
+ * const result = fn(val);
632
+ * console.log('Output:', result);
633
+ * return result;
634
+ * },
635
+ * [
636
+ * (x: number) => x + 1,
637
+ * (x: number) => x * 2,
638
+ * (x: number) => x.toString()
639
+ * ]
640
+ * );
641
+ *
642
+ * loggedPipe(5);
643
+ * // Input: 5
644
+ * // Output: 6
645
+ * // Input: 6
646
+ * // Output: 12
647
+ * // Input: 12
648
+ * // Output: '12'
649
+ * // Returns: '12'
650
+ *
651
+ * // Async transformer (resolves promises between steps)
652
+ * const asyncPipe = pipeWith(
653
+ * async (fn, val) => fn(await val),
654
+ * [
655
+ * async (x: number) => x + 1,
656
+ * async (x: number) => x * 2,
657
+ * (x: number) => x.toString()
658
+ * ]
659
+ * );
660
+ *
661
+ * await asyncPipe(Promise.resolve(5)); // '12'
662
+ *
663
+ * // Validation transformer
664
+ * const validatedPipe = pipeWith(
665
+ * (fn, val) => {
666
+ * if (val == null) throw new Error('Null value in pipeline');
667
+ * return fn(val);
668
+ * },
669
+ * [
670
+ * (x: { name: string }) => x.name,
671
+ * (name: string) => name.toUpperCase()
672
+ * ]
673
+ * );
674
+ * ```
675
+ */
676
+
677
+ /**
678
+ * Transformer function type for pipeWith.
679
+ * Uses `any` following Ramda's approach for practical usability.
680
+ */
681
+ type PipeTransformer = (fn: AnyUnaryFn, value: any) => any;
682
+ /**
683
+ * Creates a composed function with a transformer between each step.
684
+ */
685
+ declare function pipeWith<T, R>(transformer: PipeTransformer, fns: readonly AnyUnaryFn[]): (value: T) => R;
686
+ /**
687
+ * Creates a composed function that handles async operations.
688
+ *
689
+ * Each function in the pipeline can return a Promise. The pipeline
690
+ * will await each result before passing to the next function.
691
+ *
692
+ * @param fns - The functions to compose (can return Promises)
693
+ * @returns An async composed function
694
+ *
695
+ * @example
696
+ * ```ts
697
+ * const fetchAndProcess = pipeAsync(
698
+ * (id: string) => fetch(`/api/user/${id}`),
699
+ * (res: Response) => res.json(),
700
+ * (user: User) => user.name,
701
+ * (name: string) => name.toUpperCase()
702
+ * );
703
+ *
704
+ * await fetchAndProcess('123'); // 'JOHN DOE'
705
+ * ```
706
+ */
707
+ declare function pipeAsync<T, R>(...fns: readonly AnyUnaryFn[]): (value: T) => Promise<R>;
708
+ /**
709
+ * Creates a composed function from right-to-left that handles async.
710
+ *
711
+ * @param fns - The functions to compose (can return Promises)
712
+ * @returns An async composed function
713
+ */
714
+ declare function composeAsync<T, R>(...fns: readonly AnyUnaryFn[]): (value: T) => Promise<R>;
715
+
716
+ /**
717
+ * Reader operators - Pipe/Compose for functions with context
718
+ * @module core/reader
719
+ *
720
+ * Reader pattern allows passing context implicitly through a pipeline.
721
+ * Instead of `a -> b`, functions are `a -> (ctx -> b)`.
722
+ */
723
+ type ReaderFn<A, B, Ctx> = (a: A) => (ctx: Ctx) => B;
724
+ /**
725
+ * Pipes functions that return readers (Kleisli composition, left-to-right).
726
+ * Each function receives the result of the previous and the shared context.
727
+ *
728
+ * @example
729
+ * const withUser = (data) => (ctx) => ({ ...data, user: ctx.user })
730
+ * const withRole = (data) => (ctx) => ({ ...data, role: ctx.role })
731
+ *
732
+ * const process = pipeK(withUser, withRole)
733
+ * process({})({ user: 'alice', role: 'admin' })
734
+ * // { user: 'alice', role: 'admin' }
735
+ */
736
+ declare function pipeK<A, B, Ctx>(fn1: ReaderFn<A, B, Ctx>): (a: A) => (ctx: Ctx) => B;
737
+ declare function pipeK<A, B, C, Ctx>(fn1: ReaderFn<A, B, Ctx>, fn2: ReaderFn<B, C, Ctx>): (a: A) => (ctx: Ctx) => C;
738
+ declare function pipeK<A, B, C, D, Ctx>(fn1: ReaderFn<A, B, Ctx>, fn2: ReaderFn<B, C, Ctx>, fn3: ReaderFn<C, D, Ctx>): (a: A) => (ctx: Ctx) => D;
739
+ declare function pipeK<A, B, C, D, E, Ctx>(fn1: ReaderFn<A, B, Ctx>, fn2: ReaderFn<B, C, Ctx>, fn3: ReaderFn<C, D, Ctx>, fn4: ReaderFn<D, E, Ctx>): (a: A) => (ctx: Ctx) => E;
740
+ declare function pipeK<A, B, C, D, E, F, Ctx>(fn1: ReaderFn<A, B, Ctx>, fn2: ReaderFn<B, C, Ctx>, fn3: ReaderFn<C, D, Ctx>, fn4: ReaderFn<D, E, Ctx>, fn5: ReaderFn<E, F, Ctx>): (a: A) => (ctx: Ctx) => F;
741
+ /**
742
+ * Composes functions that return readers (Kleisli composition, right-to-left).
743
+ * Each function receives the result of the next and the shared context.
744
+ *
745
+ * @example
746
+ * const withUser = (data) => (ctx) => ({ ...data, user: ctx.user })
747
+ * const withRole = (data) => (ctx) => ({ ...data, role: ctx.role })
748
+ *
749
+ * const process = composeK(withRole, withUser) // right-to-left
750
+ * process({})({ user: 'alice', role: 'admin' })
751
+ * // { user: 'alice', role: 'admin' }
752
+ */
753
+ declare function composeK<A, B, Ctx>(fn1: ReaderFn<A, B, Ctx>): (a: A) => (ctx: Ctx) => B;
754
+ declare function composeK<A, B, C, Ctx>(fn2: ReaderFn<B, C, Ctx>, fn1: ReaderFn<A, B, Ctx>): (a: A) => (ctx: Ctx) => C;
755
+ declare function composeK<A, B, C, D, Ctx>(fn3: ReaderFn<C, D, Ctx>, fn2: ReaderFn<B, C, Ctx>, fn1: ReaderFn<A, B, Ctx>): (a: A) => (ctx: Ctx) => D;
756
+ declare function composeK<A, B, C, D, E, Ctx>(fn4: ReaderFn<D, E, Ctx>, fn3: ReaderFn<C, D, Ctx>, fn2: ReaderFn<B, C, Ctx>, fn1: ReaderFn<A, B, Ctx>): (a: A) => (ctx: Ctx) => E;
757
+ declare function composeK<A, B, C, D, E, F, Ctx>(fn5: ReaderFn<E, F, Ctx>, fn4: ReaderFn<D, E, Ctx>, fn3: ReaderFn<C, D, Ctx>, fn2: ReaderFn<B, C, Ctx>, fn1: ReaderFn<A, B, Ctx>): (a: A) => (ctx: Ctx) => F;
758
+
759
+ /**
760
+ * Creates local bindings for use in a body expression.
761
+ *
762
+ * `letIn` allows defining intermediate values that can depend on each other,
763
+ * then using them in a final expression. Similar to `let...in` from functional
764
+ * languages like Haskell or Clojure's `let`.
765
+ *
766
+ * The bindings are evaluated in order, so later bindings can reference
767
+ * earlier ones through the accumulated context.
768
+ *
769
+ * @param bindings - Object where keys are binding names and values are functions
770
+ * that receive the accumulated context and return the binding value
771
+ * @param body - Function that receives the final context (data + all bindings)
772
+ * and returns the result
773
+ * @param data - The input data
774
+ * @returns The result of the body function
775
+ *
776
+ * @example
777
+ * ```ts
778
+ * // Basic usage - calculate average
779
+ * const data = { items: [10, 20, 30, 40] };
780
+ *
781
+ * letIn(
782
+ * {
783
+ * total: ctx => sum(ctx.items),
784
+ * count: ctx => length(ctx.items)
785
+ * },
786
+ * ctx => divide(ctx.total, ctx.count),
787
+ * data
788
+ * );
789
+ * // 25
790
+ *
791
+ * // Curried - create reusable function
792
+ * const calcAverage = letIn(
793
+ * {
794
+ * total: pipe(prop('items'), sum),
795
+ * count: pipe(prop('items'), length)
796
+ * },
797
+ * ctx => divide(ctx.total, ctx.count)
798
+ * );
799
+ *
800
+ * calcAverage({ items: [1, 2, 3] }); // 2
801
+ *
802
+ * // Dependent bindings - each can use previous
803
+ * letIn(
804
+ * {
805
+ * items: ctx => ctx.cart.items,
806
+ * prices: ctx => pluck('price', ctx.items),
807
+ * total: ctx => sum(ctx.prices),
808
+ * count: ctx => length(ctx.prices),
809
+ * average: ctx => divide(ctx.total, ctx.count)
810
+ * },
811
+ * ctx => ctx.average,
812
+ * { cart: { items: [{ price: 10 }, { price: 20 }] } }
813
+ * );
814
+ * // 15
815
+ *
816
+ * // In a pipe
817
+ * pipe(
818
+ * data,
819
+ * letIn(
820
+ * { doubled: ctx => map(multiply(2), ctx.values) },
821
+ * ctx => sum(ctx.doubled)
822
+ * )
823
+ * );
824
+ * ```
825
+ */
826
+ type BindingFn = (ctx: any) => unknown;
827
+ type Bindings = Record<string, BindingFn>;
828
+ type BodyFn<R> = (ctx: any) => R;
829
+ declare function letIn<R>(bindings: Bindings, body: BodyFn<R>, data: object): R;
830
+ declare function letIn<R>(bindings: Bindings, body: BodyFn<R>): (data: object) => R;
831
+ declare function letIn(bindings: Bindings): {
832
+ <R>(body: BodyFn<R>, data: object): R;
833
+ <R>(body: BodyFn<R>): (data: object) => R;
834
+ };
835
+
836
+ /**
837
+ * @internal
838
+ * Placeholder symbol for curried function arguments.
839
+ *
840
+ * The placeholder allows "skipping" arguments when partially applying
841
+ * curried functions, enabling flexible argument ordering.
842
+ *
843
+ * @example
844
+ * ```ts
845
+ * import { __, subtract } from '@statedelta-libs/operators';
846
+ *
847
+ * const subtractFrom10 = subtract(__, 10); // (a) => a - 10
848
+ * subtractFrom10(15); // 5
849
+ * ```
850
+ */
851
+
852
+ /**
853
+ * The placeholder object used in curried functions.
854
+ * Marked with a unique symbol and a branded type for type safety.
855
+ */
856
+ declare const placeholder: Placeholder;
857
+ /**
858
+ * Checks if a value is the placeholder.
859
+ *
860
+ * @param value - The value to check
861
+ * @returns True if the value is the placeholder
862
+ */
863
+ declare function isPlaceholder(value: unknown): value is Placeholder;
864
+
865
+ /**
866
+ * Map operator - transforms each element of an array.
867
+ *
868
+ * @module
869
+ */
870
+ /**
871
+ * Applies a function to each element of an array and returns a new array
872
+ * with the results.
873
+ *
874
+ * This is a curried version of Array.prototype.map.
875
+ *
876
+ * @param fn - The function to apply to each element
877
+ * @param arr - The array to map over
878
+ * @returns A new array with the mapped values
879
+ *
880
+ * @example
881
+ * ```ts
882
+ * // Basic usage
883
+ * map(x => x * 2, [1, 2, 3]); // [2, 4, 6]
884
+ *
885
+ * // Curried usage
886
+ * const double = map((x: number) => x * 2);
887
+ * double([1, 2, 3]); // [2, 4, 6]
888
+ *
889
+ * // With index
890
+ * map((x, i) => `${i}: ${x}`, ['a', 'b', 'c']); // ['0: a', '1: b', '2: c']
891
+ * ```
892
+ */
893
+ declare const map: {
894
+ <T, U>(fn: (value: T, index: number, array: readonly T[]) => U, arr: readonly T[]): U[];
895
+ <T, U>(fn: (value: T, index: number, array: readonly T[]) => U): (arr: readonly T[]) => U[];
896
+ };
897
+
898
+ /**
899
+ * Filter and reject operators - filter elements of an array.
900
+ *
901
+ * @module
902
+ */
903
+ /**
904
+ * Returns a new array containing only elements that satisfy the predicate.
905
+ *
906
+ * This is a curried version of Array.prototype.filter.
907
+ *
908
+ * @param pred - The predicate function
909
+ * @param arr - The array to filter
910
+ * @returns A new array with elements that pass the predicate
911
+ *
912
+ * @example
913
+ * ```ts
914
+ * // Basic usage
915
+ * filter(x => x > 2, [1, 2, 3, 4, 5]); // [3, 4, 5]
916
+ *
917
+ * // Curried usage
918
+ * const positives = filter((x: number) => x > 0);
919
+ * positives([-1, 2, -3, 4]); // [2, 4]
920
+ *
921
+ * // With type guard
922
+ * filter((x): x is number => typeof x === 'number', [1, 'a', 2, 'b']); // [1, 2]
923
+ * ```
924
+ */
925
+ declare const filter: {
926
+ <T, S extends T>(pred: (value: T, index: number, array: readonly T[]) => value is S, arr: readonly T[]): S[];
927
+ <T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): T[];
928
+ <T, S extends T>(pred: (value: T, index: number, array: readonly T[]) => value is S): (arr: readonly T[]) => S[];
929
+ <T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => T[];
930
+ };
931
+ /**
932
+ * Returns a new array containing only elements that do NOT satisfy the predicate.
933
+ * This is the complement of `filter`.
934
+ *
935
+ * @param pred - The predicate function
936
+ * @param arr - The array to filter
937
+ * @returns A new array with elements that fail the predicate
938
+ *
939
+ * @example
940
+ * ```ts
941
+ * // Basic usage
942
+ * reject(x => x > 2, [1, 2, 3, 4, 5]); // [1, 2]
943
+ *
944
+ * // Curried usage
945
+ * const nonPositives = reject((x: number) => x > 0);
946
+ * nonPositives([-1, 2, -3, 4]); // [-1, -3]
947
+ * ```
948
+ */
949
+ declare const reject: {
950
+ <T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): T[];
951
+ <T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => T[];
952
+ };
953
+
954
+ /**
955
+ * Reduce operators - fold an array into a single value.
956
+ *
957
+ * @module
958
+ */
959
+ /**
960
+ * Reduces an array to a single value by applying a function to each element
961
+ * from left to right.
962
+ *
963
+ * This is a curried version of Array.prototype.reduce.
964
+ *
965
+ * @param fn - The reducer function (accumulator, value, index, array) => newAccumulator
966
+ * @param init - The initial accumulator value
967
+ * @param arr - The array to reduce
968
+ * @returns The final accumulated value
969
+ *
970
+ * @example
971
+ * ```ts
972
+ * // Sum
973
+ * reduce((acc, x) => acc + x, 0, [1, 2, 3, 4]); // 10
974
+ *
975
+ * // Curried usage
976
+ * const sum = reduce((acc: number, x: number) => acc + x, 0);
977
+ * sum([1, 2, 3, 4]); // 10
978
+ *
979
+ * // Build object
980
+ * reduce(
981
+ * (acc, x) => ({ ...acc, [x.id]: x }),
982
+ * {},
983
+ * [{ id: 'a', val: 1 }, { id: 'b', val: 2 }]
984
+ * );
985
+ * // { a: { id: 'a', val: 1 }, b: { id: 'b', val: 2 } }
986
+ * ```
987
+ */
988
+ declare const reduce: {
989
+ <T, U>(fn: (accumulator: U, value: T, index: number, array: readonly T[]) => U, init: U, arr: readonly T[]): U;
990
+ <T, U>(fn: (accumulator: U, value: T, index: number, array: readonly T[]) => U, init: U): (arr: readonly T[]) => U;
991
+ <T, U>(fn: (accumulator: U, value: T, index: number, array: readonly T[]) => U): {
992
+ (init: U, arr: readonly T[]): U;
993
+ (init: U): (arr: readonly T[]) => U;
994
+ };
995
+ };
996
+ /**
997
+ * Reduces an array to a single value by applying a function to each element
998
+ * from right to left.
999
+ *
1000
+ * This is a curried version of Array.prototype.reduceRight.
1001
+ *
1002
+ * @param fn - The reducer function (accumulator, value, index, array) => newAccumulator
1003
+ * @param init - The initial accumulator value
1004
+ * @param arr - The array to reduce
1005
+ * @returns The final accumulated value
1006
+ *
1007
+ * @example
1008
+ * ```ts
1009
+ * // Right to left concatenation
1010
+ * reduceRight((acc, x) => acc + x, '', ['a', 'b', 'c']); // 'cba'
1011
+ *
1012
+ * // Curried usage
1013
+ * const reverseConcat = reduceRight((acc: string, x: string) => acc + x, '');
1014
+ * reverseConcat(['a', 'b', 'c']); // 'cba'
1015
+ * ```
1016
+ */
1017
+ declare const reduceRight: {
1018
+ <T, U>(fn: (accumulator: U, value: T, index: number, array: readonly T[]) => U, init: U, arr: readonly T[]): U;
1019
+ <T, U>(fn: (accumulator: U, value: T, index: number, array: readonly T[]) => U, init: U): (arr: readonly T[]) => U;
1020
+ <T, U>(fn: (accumulator: U, value: T, index: number, array: readonly T[]) => U): {
1021
+ (init: U, arr: readonly T[]): U;
1022
+ (init: U): (arr: readonly T[]) => U;
1023
+ };
1024
+ };
1025
+
1026
+ /**
1027
+ * Slice operators - extract portions of arrays.
1028
+ *
1029
+ * @module
1030
+ */
1031
+ /**
1032
+ * Returns the first element of an array, or undefined if empty.
1033
+ *
1034
+ * @param arr - The array
1035
+ * @returns The first element or undefined
1036
+ *
1037
+ * @example
1038
+ * ```ts
1039
+ * head([1, 2, 3]); // 1
1040
+ * head([]); // undefined
1041
+ * head('abc'); // 'a'
1042
+ * ```
1043
+ */
1044
+ declare function head<T>(arr: readonly T[]): T | undefined;
1045
+ declare function head(str: string): string;
1046
+ /**
1047
+ * Returns all elements except the first.
1048
+ *
1049
+ * @param arr - The array
1050
+ * @returns A new array without the first element
1051
+ *
1052
+ * @example
1053
+ * ```ts
1054
+ * tail([1, 2, 3]); // [2, 3]
1055
+ * tail([1]); // []
1056
+ * tail([]); // []
1057
+ * ```
1058
+ */
1059
+ declare function tail<T>(arr: readonly T[]): T[];
1060
+ /**
1061
+ * Returns the last element of an array, or undefined if empty.
1062
+ *
1063
+ * @param arr - The array
1064
+ * @returns The last element or undefined
1065
+ *
1066
+ * @example
1067
+ * ```ts
1068
+ * last([1, 2, 3]); // 3
1069
+ * last([]); // undefined
1070
+ * last('abc'); // 'c'
1071
+ * ```
1072
+ */
1073
+ declare function last<T>(arr: readonly T[]): T | undefined;
1074
+ declare function last(str: string): string;
1075
+ /**
1076
+ * Returns all elements except the last.
1077
+ *
1078
+ * @param arr - The array
1079
+ * @returns A new array without the last element
1080
+ *
1081
+ * @example
1082
+ * ```ts
1083
+ * init([1, 2, 3]); // [1, 2]
1084
+ * init([1]); // []
1085
+ * init([]); // []
1086
+ * ```
1087
+ */
1088
+ declare function init<T>(arr: readonly T[]): T[];
1089
+ /**
1090
+ * Returns the element at the specified index.
1091
+ * Supports negative indices (from end).
1092
+ *
1093
+ * @param n - The index (can be negative)
1094
+ * @param arr - The array
1095
+ * @returns The element at index or undefined
1096
+ *
1097
+ * @example
1098
+ * ```ts
1099
+ * nth(2, [1, 2, 3, 4]); // 3
1100
+ * nth(-1, [1, 2, 3, 4]); // 4
1101
+ * nth(10, [1, 2, 3]); // undefined
1102
+ *
1103
+ * // Curried
1104
+ * const second = nth(1);
1105
+ * second([1, 2, 3]); // 2
1106
+ * ```
1107
+ */
1108
+ declare function nth<T>(n: number, arr: readonly T[]): T | undefined;
1109
+ declare function nth(n: number): <T>(arr: readonly T[]) => T | undefined;
1110
+ /**
1111
+ * Returns the first n elements of an array.
1112
+ *
1113
+ * @param n - The number of elements to take
1114
+ * @param arr - The array
1115
+ * @returns A new array with the first n elements
1116
+ *
1117
+ * @example
1118
+ * ```ts
1119
+ * take(3, [1, 2, 3, 4, 5]); // [1, 2, 3]
1120
+ * take(10, [1, 2]); // [1, 2]
1121
+ * take(0, [1, 2, 3]); // []
1122
+ *
1123
+ * // Curried
1124
+ * const take3 = take(3);
1125
+ * take3([1, 2, 3, 4, 5]); // [1, 2, 3]
1126
+ * ```
1127
+ */
1128
+ declare function take<T>(n: number, arr: readonly T[]): T[];
1129
+ declare function take(n: number): <T>(arr: readonly T[]) => T[];
1130
+ /**
1131
+ * Returns the last n elements of an array.
1132
+ *
1133
+ * @param n - The number of elements to take
1134
+ * @param arr - The array
1135
+ * @returns A new array with the last n elements
1136
+ *
1137
+ * @example
1138
+ * ```ts
1139
+ * takeLast(3, [1, 2, 3, 4, 5]); // [3, 4, 5]
1140
+ * takeLast(10, [1, 2]); // [1, 2]
1141
+ * takeLast(0, [1, 2, 3]); // []
1142
+ *
1143
+ * // Curried
1144
+ * const takeLast2 = takeLast(2);
1145
+ * takeLast2([1, 2, 3, 4, 5]); // [4, 5]
1146
+ * ```
1147
+ */
1148
+ declare function takeLast<T>(n: number, arr: readonly T[]): T[];
1149
+ declare function takeLast(n: number): <T>(arr: readonly T[]) => T[];
1150
+ /**
1151
+ * Returns elements from the start while the predicate returns true.
1152
+ *
1153
+ * @param pred - The predicate function
1154
+ * @param arr - The array
1155
+ * @returns A new array with elements taken while predicate is true
1156
+ *
1157
+ * @example
1158
+ * ```ts
1159
+ * takeWhile(x => x < 4, [1, 2, 3, 4, 5, 1]); // [1, 2, 3]
1160
+ *
1161
+ * // Curried
1162
+ * const takePositive = takeWhile((x: number) => x > 0);
1163
+ * takePositive([1, 2, -1, 3]); // [1, 2]
1164
+ * ```
1165
+ */
1166
+ declare function takeWhile<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): T[];
1167
+ declare function takeWhile<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => T[];
1168
+ /**
1169
+ * Returns all elements after the first n elements.
1170
+ *
1171
+ * @param n - The number of elements to drop
1172
+ * @param arr - The array
1173
+ * @returns A new array without the first n elements
1174
+ *
1175
+ * @example
1176
+ * ```ts
1177
+ * drop(3, [1, 2, 3, 4, 5]); // [4, 5]
1178
+ * drop(10, [1, 2]); // []
1179
+ * drop(0, [1, 2, 3]); // [1, 2, 3]
1180
+ *
1181
+ * // Curried
1182
+ * const drop2 = drop(2);
1183
+ * drop2([1, 2, 3, 4, 5]); // [3, 4, 5]
1184
+ * ```
1185
+ */
1186
+ declare function drop<T>(n: number, arr: readonly T[]): T[];
1187
+ declare function drop(n: number): <T>(arr: readonly T[]) => T[];
1188
+ /**
1189
+ * Returns all elements except the last n elements.
1190
+ *
1191
+ * @param n - The number of elements to drop from the end
1192
+ * @param arr - The array
1193
+ * @returns A new array without the last n elements
1194
+ *
1195
+ * @example
1196
+ * ```ts
1197
+ * dropLast(3, [1, 2, 3, 4, 5]); // [1, 2]
1198
+ * dropLast(10, [1, 2]); // []
1199
+ * dropLast(0, [1, 2, 3]); // [1, 2, 3]
1200
+ *
1201
+ * // Curried
1202
+ * const dropLast2 = dropLast(2);
1203
+ * dropLast2([1, 2, 3, 4, 5]); // [1, 2, 3]
1204
+ * ```
1205
+ */
1206
+ declare function dropLast<T>(n: number, arr: readonly T[]): T[];
1207
+ declare function dropLast(n: number): <T>(arr: readonly T[]) => T[];
1208
+ /**
1209
+ * Drops elements from the start while the predicate returns true.
1210
+ *
1211
+ * @param pred - The predicate function
1212
+ * @param arr - The array
1213
+ * @returns A new array with elements dropped while predicate was true
1214
+ *
1215
+ * @example
1216
+ * ```ts
1217
+ * dropWhile(x => x < 4, [1, 2, 3, 4, 5, 1]); // [4, 5, 1]
1218
+ *
1219
+ * // Curried
1220
+ * const dropNegative = dropWhile((x: number) => x < 0);
1221
+ * dropNegative([-2, -1, 0, 1, 2]); // [0, 1, 2]
1222
+ * ```
1223
+ */
1224
+ declare function dropWhile<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): T[];
1225
+ declare function dropWhile<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => T[];
1226
+ /**
1227
+ * Returns a portion of an array from start index to end index (exclusive).
1228
+ * Supports negative indices.
1229
+ *
1230
+ * @param start - The start index (inclusive)
1231
+ * @param end - The end index (exclusive)
1232
+ * @param arr - The array
1233
+ * @returns A new array with the sliced portion
1234
+ *
1235
+ * @example
1236
+ * ```ts
1237
+ * slice(1, 4, [0, 1, 2, 3, 4, 5]); // [1, 2, 3]
1238
+ * slice(-3, -1, [0, 1, 2, 3, 4]); // [2, 3]
1239
+ *
1240
+ * // Curried
1241
+ * const middle = slice(1, -1);
1242
+ * middle([0, 1, 2, 3, 4]); // [1, 2, 3]
1243
+ * ```
1244
+ */
1245
+ declare function slice<T>(start: number, end: number, arr: readonly T[]): T[];
1246
+ declare function slice(start: number, end: number): <T>(arr: readonly T[]) => T[];
1247
+ declare function slice(start: number): {
1248
+ <T>(end: number, arr: readonly T[]): T[];
1249
+ (end: number): <T>(arr: readonly T[]) => T[];
1250
+ };
1251
+
1252
+ /**
1253
+ * Find operators - search for elements in arrays.
1254
+ *
1255
+ * @module
1256
+ */
1257
+ /**
1258
+ * Returns the first element that satisfies the predicate, or undefined.
1259
+ *
1260
+ * @param pred - The predicate function
1261
+ * @param arr - The array to search
1262
+ * @returns The first matching element or undefined
1263
+ *
1264
+ * @example
1265
+ * ```ts
1266
+ * find(x => x > 2, [1, 2, 3, 4]); // 3
1267
+ * find(x => x > 10, [1, 2, 3]); // undefined
1268
+ *
1269
+ * // Curried
1270
+ * const findEven = find((x: number) => x % 2 === 0);
1271
+ * findEven([1, 3, 4, 5]); // 4
1272
+ * ```
1273
+ */
1274
+ declare function find<T, S extends T>(pred: (value: T, index: number, array: readonly T[]) => value is S, arr: readonly T[]): S | undefined;
1275
+ declare function find<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): T | undefined;
1276
+ declare function find<T, S extends T>(pred: (value: T, index: number, array: readonly T[]) => value is S): (arr: readonly T[]) => S | undefined;
1277
+ declare function find<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => T | undefined;
1278
+ /**
1279
+ * Returns the index of the first element that satisfies the predicate, or -1.
1280
+ *
1281
+ * @param pred - The predicate function
1282
+ * @param arr - The array to search
1283
+ * @returns The index of the first match or -1
1284
+ *
1285
+ * @example
1286
+ * ```ts
1287
+ * findIndex(x => x > 2, [1, 2, 3, 4]); // 2
1288
+ * findIndex(x => x > 10, [1, 2, 3]); // -1
1289
+ *
1290
+ * // Curried
1291
+ * const findEvenIdx = findIndex((x: number) => x % 2 === 0);
1292
+ * findEvenIdx([1, 3, 4, 5]); // 2
1293
+ * ```
1294
+ */
1295
+ declare function findIndex<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): number;
1296
+ declare function findIndex<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => number;
1297
+ /**
1298
+ * Returns the last element that satisfies the predicate, or undefined.
1299
+ *
1300
+ * @param pred - The predicate function
1301
+ * @param arr - The array to search
1302
+ * @returns The last matching element or undefined
1303
+ *
1304
+ * @example
1305
+ * ```ts
1306
+ * findLast(x => x % 2 === 0, [1, 2, 3, 4, 5]); // 4
1307
+ * findLast(x => x > 10, [1, 2, 3]); // undefined
1308
+ *
1309
+ * // Curried
1310
+ * const findLastEven = findLast((x: number) => x % 2 === 0);
1311
+ * findLastEven([1, 2, 3, 4, 5]); // 4
1312
+ * ```
1313
+ */
1314
+ declare function findLast<T, S extends T>(pred: (value: T, index: number, array: readonly T[]) => value is S, arr: readonly T[]): S | undefined;
1315
+ declare function findLast<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): T | undefined;
1316
+ declare function findLast<T, S extends T>(pred: (value: T, index: number, array: readonly T[]) => value is S): (arr: readonly T[]) => S | undefined;
1317
+ declare function findLast<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => T | undefined;
1318
+ /**
1319
+ * Returns the index of the first occurrence of a value, or -1.
1320
+ * Uses strict equality (===).
1321
+ *
1322
+ * @param value - The value to find
1323
+ * @param arr - The array to search
1324
+ * @returns The index of the value or -1
1325
+ *
1326
+ * @example
1327
+ * ```ts
1328
+ * indexOf(3, [1, 2, 3, 4, 3]); // 2
1329
+ * indexOf(10, [1, 2, 3]); // -1
1330
+ *
1331
+ * // Curried
1332
+ * const findThree = indexOf(3);
1333
+ * findThree([1, 2, 3, 4]); // 2
1334
+ * ```
1335
+ */
1336
+ declare function indexOf<T>(value: T, arr: readonly T[]): number;
1337
+ declare function indexOf<T>(value: T): (arr: readonly T[]) => number;
1338
+ /**
1339
+ * Returns true if the array contains the specified value.
1340
+ * Uses strict equality (===).
1341
+ *
1342
+ * @param value - The value to find
1343
+ * @param arr - The array to search
1344
+ * @returns True if the value is found
1345
+ *
1346
+ * @example
1347
+ * ```ts
1348
+ * includes(3, [1, 2, 3, 4]); // true
1349
+ * includes(10, [1, 2, 3]); // false
1350
+ *
1351
+ * // Curried
1352
+ * const hasThree = includes(3);
1353
+ * hasThree([1, 2, 3, 4]); // true
1354
+ * hasThree([1, 2, 4]); // false
1355
+ * ```
1356
+ */
1357
+ declare function includes<T>(value: T, arr: readonly T[]): boolean;
1358
+ declare function includes<T>(value: T): (arr: readonly T[]) => boolean;
1359
+
1360
+ /**
1361
+ * Transform operators - advanced array transformations.
1362
+ *
1363
+ * @module
1364
+ */
1365
+ /**
1366
+ * Flattens a nested array by one level.
1367
+ *
1368
+ * @param arr - The array to flatten
1369
+ * @returns A new flattened array
1370
+ *
1371
+ * @example
1372
+ * ```ts
1373
+ * flatten([[1, 2], [3, 4], [5]]); // [1, 2, 3, 4, 5]
1374
+ * flatten([[1, [2]], [3]]); // [1, [2], 3] (only one level)
1375
+ * flatten([]); // []
1376
+ * ```
1377
+ */
1378
+ declare function flatten<T>(arr: readonly (T | readonly T[])[]): T[];
1379
+ /**
1380
+ * Alias for flatten. Removes one level of nesting.
1381
+ *
1382
+ * @param arr - The array to unnest
1383
+ * @returns A new flattened array
1384
+ *
1385
+ * @example
1386
+ * ```ts
1387
+ * unnest([[1, 2], [3, 4]]); // [1, 2, 3, 4]
1388
+ * ```
1389
+ */
1390
+ declare const unnest: typeof flatten;
1391
+ /**
1392
+ * Maps a function over a list and concatenates the results (flatMap).
1393
+ *
1394
+ * @param fn - The function to apply
1395
+ * @param arr - The array to map over
1396
+ * @returns A new flattened array of results
1397
+ *
1398
+ * @example
1399
+ * ```ts
1400
+ * chain(x => [x, x * 2], [1, 2, 3]); // [1, 2, 2, 4, 3, 6]
1401
+ *
1402
+ * // Curried
1403
+ * const duplicate = chain((x: number) => [x, x]);
1404
+ * duplicate([1, 2, 3]); // [1, 1, 2, 2, 3, 3]
1405
+ * ```
1406
+ */
1407
+ declare function chain<T, U>(fn: (value: T, index: number, array: readonly T[]) => readonly U[], arr: readonly T[]): U[];
1408
+ declare function chain<T, U>(fn: (value: T, index: number, array: readonly T[]) => readonly U[]): (arr: readonly T[]) => U[];
1409
+ /**
1410
+ * Returns a new array with duplicate values removed.
1411
+ * Uses strict equality (===).
1412
+ *
1413
+ * @param arr - The array to deduplicate
1414
+ * @returns A new array with unique values
1415
+ *
1416
+ * @example
1417
+ * ```ts
1418
+ * uniq([1, 2, 1, 3, 2, 4]); // [1, 2, 3, 4]
1419
+ * uniq(['a', 'b', 'a']); // ['a', 'b']
1420
+ * ```
1421
+ */
1422
+ declare function uniq<T>(arr: readonly T[]): T[];
1423
+ /**
1424
+ * Returns a new array with duplicate values removed based on a key function.
1425
+ *
1426
+ * @param fn - Function to generate the key for comparison
1427
+ * @param arr - The array to deduplicate
1428
+ * @returns A new array with unique values by key
1429
+ *
1430
+ * @example
1431
+ * ```ts
1432
+ * uniqBy(Math.abs, [1, -1, 2, -2, 3]); // [1, 2, 3]
1433
+ *
1434
+ * // With objects
1435
+ * uniqBy(x => x.id, [{id: 1}, {id: 2}, {id: 1}]); // [{id: 1}, {id: 2}]
1436
+ *
1437
+ * // Curried
1438
+ * const uniqById = uniqBy((x: {id: number}) => x.id);
1439
+ * ```
1440
+ */
1441
+ declare function uniqBy<T, K>(fn: (value: T) => K, arr: readonly T[]): T[];
1442
+ declare function uniqBy<T, K>(fn: (value: T) => K): (arr: readonly T[]) => T[];
1443
+ /**
1444
+ * Returns a sorted copy of an array using a comparator function.
1445
+ *
1446
+ * @param comparator - Function (a, b) => number for comparison
1447
+ * @param arr - The array to sort
1448
+ * @returns A new sorted array
1449
+ *
1450
+ * @example
1451
+ * ```ts
1452
+ * sort((a, b) => a - b, [3, 1, 4, 1, 5]); // [1, 1, 3, 4, 5]
1453
+ * sort((a, b) => b - a, [3, 1, 4, 1, 5]); // [5, 4, 3, 1, 1]
1454
+ *
1455
+ * // Curried
1456
+ * const sortAsc = sort((a: number, b: number) => a - b);
1457
+ * sortAsc([3, 1, 2]); // [1, 2, 3]
1458
+ * ```
1459
+ */
1460
+ declare function sort<T>(comparator: (a: T, b: T) => number, arr: readonly T[]): T[];
1461
+ declare function sort<T>(comparator: (a: T, b: T) => number): (arr: readonly T[]) => T[];
1462
+ /**
1463
+ * Returns a sorted copy of an array using a function to extract the sort key.
1464
+ *
1465
+ * @param fn - Function to extract the sort key
1466
+ * @param arr - The array to sort
1467
+ * @returns A new sorted array
1468
+ *
1469
+ * @example
1470
+ * ```ts
1471
+ * sortBy(x => x.age, [{name: 'Bob', age: 30}, {name: 'Alice', age: 25}]);
1472
+ * // [{name: 'Alice', age: 25}, {name: 'Bob', age: 30}]
1473
+ *
1474
+ * sortBy(x => x.length, ['aaa', 'a', 'aa']); // ['a', 'aa', 'aaa']
1475
+ *
1476
+ * // Curried
1477
+ * const sortByAge = sortBy((x: {age: number}) => x.age);
1478
+ * ```
1479
+ */
1480
+ declare function sortBy<T, U extends number | string>(fn: (value: T) => U, arr: readonly T[]): T[];
1481
+ declare function sortBy<T, U extends number | string>(fn: (value: T) => U): (arr: readonly T[]) => T[];
1482
+ /**
1483
+ * Returns a new array with elements in reverse order.
1484
+ *
1485
+ * @param arr - The array to reverse
1486
+ * @returns A new reversed array
1487
+ *
1488
+ * @example
1489
+ * ```ts
1490
+ * reverse([1, 2, 3]); // [3, 2, 1]
1491
+ * reverse('abc'); // ['c', 'b', 'a']
1492
+ * ```
1493
+ */
1494
+ declare function reverse<T>(arr: readonly T[]): T[];
1495
+ /**
1496
+ * Groups array elements by a key function.
1497
+ *
1498
+ * @param fn - Function to generate the grouping key
1499
+ * @param arr - The array to group
1500
+ * @returns An object with keys and grouped arrays
1501
+ *
1502
+ * @example
1503
+ * ```ts
1504
+ * groupBy(x => x.type, [
1505
+ * {type: 'a', val: 1},
1506
+ * {type: 'b', val: 2},
1507
+ * {type: 'a', val: 3}
1508
+ * ]);
1509
+ * // { a: [{type:'a',val:1}, {type:'a',val:3}], b: [{type:'b',val:2}] }
1510
+ *
1511
+ * groupBy(x => x % 2 === 0 ? 'even' : 'odd', [1, 2, 3, 4, 5]);
1512
+ * // { odd: [1, 3, 5], even: [2, 4] }
1513
+ *
1514
+ * // Curried
1515
+ * const groupByType = groupBy((x: {type: string}) => x.type);
1516
+ * ```
1517
+ */
1518
+ declare function groupBy<T, K extends string | number>(fn: (value: T) => K, arr: readonly T[]): Record<K, T[]>;
1519
+ declare function groupBy<T, K extends string | number>(fn: (value: T) => K): (arr: readonly T[]) => Record<K, T[]>;
1520
+
1521
+ /**
1522
+ * Combine operators - combine and merge arrays.
1523
+ *
1524
+ * @module
1525
+ */
1526
+ /**
1527
+ * Concatenates two arrays.
1528
+ *
1529
+ * @param arr1 - The first array
1530
+ * @param arr2 - The second array
1531
+ * @returns A new concatenated array
1532
+ *
1533
+ * @example
1534
+ * ```ts
1535
+ * concat([1, 2], [3, 4]); // [1, 2, 3, 4]
1536
+ * concat([], [1, 2]); // [1, 2]
1537
+ *
1538
+ * // Curried
1539
+ * const prependAB = concat(['a', 'b']);
1540
+ * prependAB(['c', 'd']); // ['a', 'b', 'c', 'd']
1541
+ * ```
1542
+ */
1543
+ declare function concat<T>(arr1: readonly T[], arr2: readonly T[]): T[];
1544
+ declare function concat<T>(arr1: readonly T[]): (arr2: readonly T[]) => T[];
1545
+ /**
1546
+ * Adds an element to the end of an array.
1547
+ *
1548
+ * @param value - The value to append
1549
+ * @param arr - The array
1550
+ * @returns A new array with the value appended
1551
+ *
1552
+ * @example
1553
+ * ```ts
1554
+ * append(4, [1, 2, 3]); // [1, 2, 3, 4]
1555
+ * append('d', ['a', 'b', 'c']); // ['a', 'b', 'c', 'd']
1556
+ *
1557
+ * // Curried
1558
+ * const addZero = append(0);
1559
+ * addZero([1, 2, 3]); // [1, 2, 3, 0]
1560
+ * ```
1561
+ */
1562
+ declare function append<T>(value: T, arr: readonly T[]): T[];
1563
+ declare function append<T>(value: T): (arr: readonly T[]) => T[];
1564
+ /**
1565
+ * Adds an element to the beginning of an array.
1566
+ *
1567
+ * @param value - The value to prepend
1568
+ * @param arr - The array
1569
+ * @returns A new array with the value prepended
1570
+ *
1571
+ * @example
1572
+ * ```ts
1573
+ * prepend(0, [1, 2, 3]); // [0, 1, 2, 3]
1574
+ * prepend('a', ['b', 'c']); // ['a', 'b', 'c']
1575
+ *
1576
+ * // Curried
1577
+ * const addZero = prepend(0);
1578
+ * addZero([1, 2, 3]); // [0, 1, 2, 3]
1579
+ * ```
1580
+ */
1581
+ declare function prepend<T>(value: T, arr: readonly T[]): T[];
1582
+ declare function prepend<T>(value: T): (arr: readonly T[]) => T[];
1583
+ /**
1584
+ * Creates pairs from two arrays.
1585
+ *
1586
+ * @param arr1 - The first array
1587
+ * @param arr2 - The second array
1588
+ * @returns An array of pairs
1589
+ *
1590
+ * @example
1591
+ * ```ts
1592
+ * zip([1, 2, 3], ['a', 'b', 'c']); // [[1, 'a'], [2, 'b'], [3, 'c']]
1593
+ * zip([1, 2], ['a', 'b', 'c']); // [[1, 'a'], [2, 'b']] (truncates to shorter)
1594
+ *
1595
+ * // Curried
1596
+ * const zipWithNumbers = zip([1, 2, 3]);
1597
+ * zipWithNumbers(['a', 'b', 'c']); // [[1, 'a'], [2, 'b'], [3, 'c']]
1598
+ * ```
1599
+ */
1600
+ declare function zip<T, U>(arr1: readonly T[], arr2: readonly U[]): [T, U][];
1601
+ declare function zip<T>(arr1: readonly T[]): <U>(arr2: readonly U[]) => [T, U][];
1602
+ /**
1603
+ * Combines two arrays using a function.
1604
+ *
1605
+ * @param fn - The combining function
1606
+ * @param arr1 - The first array
1607
+ * @param arr2 - The second array
1608
+ * @returns An array of combined values
1609
+ *
1610
+ * @example
1611
+ * ```ts
1612
+ * zipWith((a, b) => a + b, [1, 2, 3], [10, 20, 30]); // [11, 22, 33]
1613
+ * zipWith((a, b) => a * b, [1, 2], [3, 4]); // [3, 8]
1614
+ *
1615
+ * // Curried
1616
+ * const addPairs = zipWith((a: number, b: number) => a + b);
1617
+ * addPairs([1, 2, 3], [10, 20, 30]); // [11, 22, 33]
1618
+ * ```
1619
+ */
1620
+ declare function zipWith<T, U, R>(fn: (a: T, b: U) => R, arr1: readonly T[], arr2: readonly U[]): R[];
1621
+ declare function zipWith<T, U, R>(fn: (a: T, b: U) => R, arr1: readonly T[]): (arr2: readonly U[]) => R[];
1622
+ declare function zipWith<T, U, R>(fn: (a: T, b: U) => R): {
1623
+ (arr1: readonly T[], arr2: readonly U[]): R[];
1624
+ (arr1: readonly T[]): (arr2: readonly U[]) => R[];
1625
+ };
1626
+ /**
1627
+ * Creates an object from arrays of keys and values.
1628
+ *
1629
+ * @param keys - The array of keys
1630
+ * @param values - The array of values
1631
+ * @returns An object mapping keys to values
1632
+ *
1633
+ * @example
1634
+ * ```ts
1635
+ * zipObj(['a', 'b', 'c'], [1, 2, 3]); // { a: 1, b: 2, c: 3 }
1636
+ * zipObj(['x', 'y'], [10, 20, 30]); // { x: 10, y: 20 } (truncates)
1637
+ *
1638
+ * // Curried
1639
+ * const createObj = zipObj(['name', 'age']);
1640
+ * createObj(['Alice', 30]); // { name: 'Alice', age: 30 }
1641
+ * ```
1642
+ */
1643
+ declare function zipObj<K extends string | number, V>(keys: readonly K[], values: readonly V[]): Record<K, V>;
1644
+ declare function zipObj<K extends string | number>(keys: readonly K[]): <V>(values: readonly V[]) => Record<K, V>;
1645
+
1646
+ /**
1647
+ * Predicate operators - test arrays against conditions.
1648
+ *
1649
+ * @module
1650
+ */
1651
+ /**
1652
+ * Returns true if at least one element satisfies the predicate.
1653
+ *
1654
+ * @param pred - The predicate function
1655
+ * @param arr - The array to test
1656
+ * @returns True if any element passes the predicate
1657
+ *
1658
+ * @example
1659
+ * ```ts
1660
+ * some(x => x > 3, [1, 2, 3, 4, 5]); // true
1661
+ * some(x => x > 10, [1, 2, 3]); // false
1662
+ * some(x => x > 0, []); // false (empty array)
1663
+ *
1664
+ * // Curried
1665
+ * const hasNegative = some((x: number) => x < 0);
1666
+ * hasNegative([1, -2, 3]); // true
1667
+ * hasNegative([1, 2, 3]); // false
1668
+ * ```
1669
+ */
1670
+ declare function some<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): boolean;
1671
+ declare function some<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => boolean;
1672
+ /**
1673
+ * Returns true if all elements satisfy the predicate.
1674
+ *
1675
+ * @param pred - The predicate function
1676
+ * @param arr - The array to test
1677
+ * @returns True if all elements pass the predicate
1678
+ *
1679
+ * @example
1680
+ * ```ts
1681
+ * every(x => x > 0, [1, 2, 3]); // true
1682
+ * every(x => x > 0, [1, -2, 3]); // false
1683
+ * every(x => x > 0, []); // true (vacuous truth)
1684
+ *
1685
+ * // Curried
1686
+ * const allPositive = every((x: number) => x > 0);
1687
+ * allPositive([1, 2, 3]); // true
1688
+ * allPositive([1, -2, 3]); // false
1689
+ * ```
1690
+ */
1691
+ declare function every<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): boolean;
1692
+ declare function every<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => boolean;
1693
+ /**
1694
+ * Returns true if no elements satisfy the predicate.
1695
+ *
1696
+ * @param pred - The predicate function
1697
+ * @param arr - The array to test
1698
+ * @returns True if no elements pass the predicate
1699
+ *
1700
+ * @example
1701
+ * ```ts
1702
+ * none(x => x < 0, [1, 2, 3]); // true
1703
+ * none(x => x < 0, [1, -2, 3]); // false
1704
+ * none(x => x > 0, []); // true (empty array)
1705
+ *
1706
+ * // Curried
1707
+ * const noNegatives = none((x: number) => x < 0);
1708
+ * noNegatives([1, 2, 3]); // true
1709
+ * noNegatives([1, -2, 3]); // false
1710
+ * ```
1711
+ */
1712
+ declare function none<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): boolean;
1713
+ declare function none<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => boolean;
1714
+
1715
+ /**
1716
+ * Aggregate operators - compute values from arrays.
1717
+ *
1718
+ * @module
1719
+ */
1720
+ /**
1721
+ * Returns the length of an array or string.
1722
+ *
1723
+ * @param arr - The array or string
1724
+ * @returns The length
1725
+ *
1726
+ * @example
1727
+ * ```ts
1728
+ * length([1, 2, 3]); // 3
1729
+ * length('hello'); // 5
1730
+ * length([]); // 0
1731
+ * ```
1732
+ */
1733
+ declare function length(arr: readonly unknown[] | string): number;
1734
+ /**
1735
+ * Returns the sum of all numbers in an array.
1736
+ *
1737
+ * @param arr - The array of numbers
1738
+ * @returns The sum
1739
+ *
1740
+ * @example
1741
+ * ```ts
1742
+ * sum([1, 2, 3, 4]); // 10
1743
+ * sum([]); // 0
1744
+ * sum([5]); // 5
1745
+ * ```
1746
+ */
1747
+ declare function sum(arr: readonly number[]): number;
1748
+ /**
1749
+ * Returns the product of all numbers in an array.
1750
+ *
1751
+ * @param arr - The array of numbers
1752
+ * @returns The product
1753
+ *
1754
+ * @example
1755
+ * ```ts
1756
+ * product([1, 2, 3, 4]); // 24
1757
+ * product([]); // 1 (identity for multiplication)
1758
+ * product([5]); // 5
1759
+ * ```
1760
+ */
1761
+ declare function product(arr: readonly number[]): number;
1762
+ /**
1763
+ * Returns the arithmetic mean (average) of an array of numbers.
1764
+ *
1765
+ * @param arr - The array of numbers
1766
+ * @returns The mean, or NaN for empty arrays
1767
+ *
1768
+ * @example
1769
+ * ```ts
1770
+ * mean([1, 2, 3, 4, 5]); // 3
1771
+ * mean([10, 20]); // 15
1772
+ * mean([]); // NaN
1773
+ * ```
1774
+ */
1775
+ declare function mean(arr: readonly number[]): number;
1776
+ /**
1777
+ * Returns the median of an array of numbers.
1778
+ * For even-length arrays, returns the average of the two middle values.
1779
+ *
1780
+ * @param arr - The array of numbers
1781
+ * @returns The median, or NaN for empty arrays
1782
+ *
1783
+ * @example
1784
+ * ```ts
1785
+ * median([1, 2, 3, 4, 5]); // 3
1786
+ * median([1, 2, 3, 4]); // 2.5
1787
+ * median([7, 1, 3]); // 3
1788
+ * median([]); // NaN
1789
+ * ```
1790
+ */
1791
+ declare function median(arr: readonly number[]): number;
1792
+ /**
1793
+ * Returns the minimum value in an array.
1794
+ *
1795
+ * @param arr - The array of numbers
1796
+ * @returns The minimum value, or Infinity for empty arrays
1797
+ *
1798
+ * @example
1799
+ * ```ts
1800
+ * min([3, 1, 4, 1, 5]); // 1
1801
+ * min([-1, -5, -2]); // -5
1802
+ * min([]); // Infinity
1803
+ * ```
1804
+ */
1805
+ declare function min(arr: readonly number[]): number;
1806
+ /**
1807
+ * Returns the maximum value in an array.
1808
+ *
1809
+ * @param arr - The array of numbers
1810
+ * @returns The maximum value, or -Infinity for empty arrays
1811
+ *
1812
+ * @example
1813
+ * ```ts
1814
+ * max([3, 1, 4, 1, 5]); // 5
1815
+ * max([-1, -5, -2]); // -1
1816
+ * max([]); // -Infinity
1817
+ * ```
1818
+ */
1819
+ declare function max(arr: readonly number[]): number;
1820
+ /**
1821
+ * Counts elements by a key function.
1822
+ *
1823
+ * @param fn - Function to generate the counting key
1824
+ * @param arr - The array to count
1825
+ * @returns An object with keys and their counts
1826
+ *
1827
+ * @example
1828
+ * ```ts
1829
+ * countBy(x => x.type, [
1830
+ * {type: 'a'}, {type: 'b'}, {type: 'a'}
1831
+ * ]);
1832
+ * // { a: 2, b: 1 }
1833
+ *
1834
+ * countBy(Math.floor, [1.1, 2.2, 2.8, 3.1]);
1835
+ * // { '1': 1, '2': 2, '3': 1 }
1836
+ *
1837
+ * // Curried
1838
+ * const countByLength = countBy((s: string) => s.length);
1839
+ * countByLength(['a', 'bb', 'ccc', 'dd']); // { '1': 1, '2': 2, '3': 1 }
1840
+ * ```
1841
+ */
1842
+ declare function countBy<T, K extends string | number>(fn: (value: T) => K, arr: readonly T[]): Record<K, number>;
1843
+ declare function countBy<T, K extends string | number>(fn: (value: T) => K): (arr: readonly T[]) => Record<K, number>;
1844
+
1845
+ /**
1846
+ * Partition operators - split and generate arrays.
1847
+ *
1848
+ * @module
1849
+ */
1850
+ /**
1851
+ * Generates an array of numbers from start (inclusive) to end (exclusive).
1852
+ *
1853
+ * @param start - The starting number (inclusive)
1854
+ * @param end - The ending number (exclusive)
1855
+ * @returns An array of numbers
1856
+ *
1857
+ * @example
1858
+ * ```ts
1859
+ * range(1, 5); // [1, 2, 3, 4]
1860
+ * range(0, 3); // [0, 1, 2]
1861
+ * range(5, 5); // []
1862
+ * range(3, 1); // [] (start > end)
1863
+ * ```
1864
+ */
1865
+ declare function range(start: number, end: number): number[];
1866
+ declare function range(start: number): (end: number) => number[];
1867
+ /**
1868
+ * Splits an array into two groups based on a predicate.
1869
+ * Returns [passing, failing] arrays.
1870
+ *
1871
+ * @param pred - The predicate function
1872
+ * @param arr - The array to partition
1873
+ * @returns A tuple of [elements that pass, elements that fail]
1874
+ *
1875
+ * @example
1876
+ * ```ts
1877
+ * partition(x => x > 0, [-1, 2, -3, 4]);
1878
+ * // [[2, 4], [-1, -3]]
1879
+ *
1880
+ * partition(x => x % 2 === 0, [1, 2, 3, 4, 5]);
1881
+ * // [[2, 4], [1, 3, 5]]
1882
+ *
1883
+ * // Curried
1884
+ * const splitBySign = partition((x: number) => x >= 0);
1885
+ * splitBySign([-1, 2, -3, 4]); // [[2, 4], [-1, -3]]
1886
+ * ```
1887
+ */
1888
+ declare function partition<T>(pred: (value: T, index: number, array: readonly T[]) => boolean, arr: readonly T[]): [T[], T[]];
1889
+ declare function partition<T>(pred: (value: T, index: number, array: readonly T[]) => boolean): (arr: readonly T[]) => [T[], T[]];
1890
+ /**
1891
+ * Splits an array into chunks of a specified size.
1892
+ *
1893
+ * @param n - The chunk size
1894
+ * @param arr - The array to split
1895
+ * @returns An array of chunks
1896
+ *
1897
+ * @example
1898
+ * ```ts
1899
+ * splitEvery(2, [1, 2, 3, 4, 5]); // [[1, 2], [3, 4], [5]]
1900
+ * splitEvery(3, [1, 2, 3, 4, 5]); // [[1, 2, 3], [4, 5]]
1901
+ * splitEvery(5, [1, 2, 3]); // [[1, 2, 3]]
1902
+ *
1903
+ * // Curried
1904
+ * const pairs = splitEvery(2);
1905
+ * pairs([1, 2, 3, 4]); // [[1, 2], [3, 4]]
1906
+ * ```
1907
+ */
1908
+ declare function splitEvery<T>(n: number, arr: readonly T[]): T[][];
1909
+ declare function splitEvery(n: number): <T>(arr: readonly T[]) => T[][];
1910
+ /**
1911
+ * Creates an object from an array, indexed by a key function.
1912
+ * If multiple items have the same key, the last one wins.
1913
+ *
1914
+ * @param fn - Function to generate the key for each element
1915
+ * @param arr - The array to index
1916
+ * @returns An object mapping keys to elements
1917
+ *
1918
+ * @example
1919
+ * ```ts
1920
+ * indexBy(x => x.id, [
1921
+ * { id: 'a', val: 1 },
1922
+ * { id: 'b', val: 2 }
1923
+ * ]);
1924
+ * // { a: { id: 'a', val: 1 }, b: { id: 'b', val: 2 } }
1925
+ *
1926
+ * // Curried
1927
+ * const byId = indexBy((x: {id: string}) => x.id);
1928
+ * byId([{ id: 'x', name: 'Item X' }]); // { x: { id: 'x', name: 'Item X' } }
1929
+ * ```
1930
+ */
1931
+ declare function indexBy<T, K extends string | number>(fn: (value: T) => K, arr: readonly T[]): Record<K, T>;
1932
+ declare function indexBy<T, K extends string | number>(fn: (value: T) => K): (arr: readonly T[]) => Record<K, T>;
1933
+
1934
+ /**
1935
+ * Object access operators
1936
+ * @module object/access
1937
+ */
1938
+ declare function prop<K extends string>(key: K): <T extends Record<K, unknown>>(obj: T) => T[K];
1939
+ declare function prop<T, K extends keyof T>(key: K, obj: T): T[K];
1940
+ declare function path<T = unknown>(keys: readonly (string | number)[]): (obj: unknown) => T | undefined;
1941
+ declare function path<T = unknown>(keys: readonly (string | number)[], obj: unknown): T | undefined;
1942
+ declare function propOr<D>(defaultValue: D): {
1943
+ <K extends string>(key: K): <T extends Record<K, unknown>>(obj: T) => T[K] | D;
1944
+ <K extends string, T extends Record<K, unknown>>(key: K, obj: T): T[K] | D;
1945
+ };
1946
+ declare function propOr<D, K extends string>(defaultValue: D, key: K): <T extends Record<K, unknown>>(obj: T) => T[K] | D;
1947
+ declare function propOr<D, K extends keyof T, T>(defaultValue: D, key: K, obj: T): T[K] | D;
1948
+ declare function pathOr<D>(defaultValue: D): {
1949
+ (keys: readonly (string | number)[]): (obj: unknown) => unknown | D;
1950
+ (keys: readonly (string | number)[], obj: unknown): unknown | D;
1951
+ };
1952
+ declare function pathOr<D>(defaultValue: D, keys: readonly (string | number)[]): (obj: unknown) => unknown | D;
1953
+ declare function pathOr<D>(defaultValue: D, keys: readonly (string | number)[], obj: unknown): unknown | D;
1954
+ declare function props<K extends string>(keys: readonly K[]): <T extends Record<K, unknown>>(obj: T) => T[K][];
1955
+ declare function props<T, K extends keyof T>(keys: readonly K[], obj: T): T[K][];
1956
+ declare function pluck<K extends string>(key: K): <T extends Record<K, unknown>>(arr: readonly T[]) => T[K][];
1957
+ declare function pluck<T, K extends keyof T>(key: K, arr: readonly T[]): T[K][];
1958
+
1959
+ /**
1960
+ * Object transform operators
1961
+ * @module object/transform
1962
+ */
1963
+ declare function assoc<K extends string>(key: K): {
1964
+ <V>(val: V): <T extends Record<string, unknown>>(obj: T) => T & Record<K, V>;
1965
+ <V, T extends Record<string, unknown>>(val: V, obj: T): T & Record<K, V>;
1966
+ };
1967
+ declare function assoc<K extends string, V>(key: K, val: V): <T extends Record<string, unknown>>(obj: T) => T & Record<K, V>;
1968
+ declare function assoc<K extends string, V, T extends Record<string, unknown>>(key: K, val: V, obj: T): T & Record<K, V>;
1969
+ declare function assocPath(keys: readonly (string | number)[]): {
1970
+ <V>(val: V): (obj: unknown) => unknown;
1971
+ <V>(val: V, obj: unknown): unknown;
1972
+ };
1973
+ declare function assocPath<V>(keys: readonly (string | number)[], val: V): (obj: unknown) => unknown;
1974
+ declare function assocPath<V>(keys: readonly (string | number)[], val: V, obj: unknown): unknown;
1975
+ declare function dissoc<K extends string>(key: K): <T extends Record<string, unknown>>(obj: T) => Omit<T, K>;
1976
+ declare function dissoc<K extends string, T extends Record<string, unknown>>(key: K, obj: T): Omit<T, K>;
1977
+ declare function dissocPath(keys: readonly (string | number)[]): (obj: unknown) => unknown;
1978
+ declare function dissocPath(keys: readonly (string | number)[], obj: unknown): unknown;
1979
+ declare function pick<K extends string>(keys: readonly K[]): <T extends Record<K, unknown>>(obj: T) => Pick<T, K>;
1980
+ declare function pick<T extends Record<string, unknown>, K extends keyof T>(keys: readonly K[], obj: T): Pick<T, K>;
1981
+ declare function omit<K extends string>(keys: readonly K[]): <T extends Record<string, unknown>>(obj: T) => Omit<T, K>;
1982
+ declare function omit<T extends Record<string, unknown>, K extends keyof T>(keys: readonly K[], obj: T): Omit<T, K>;
1983
+ declare function merge<T extends Record<string, unknown>>(left: T): <U extends Record<string, unknown>>(right: U) => T & U;
1984
+ declare function merge<T extends Record<string, unknown>, U extends Record<string, unknown>>(left: T, right: U): T & U;
1985
+ declare function mergeDeep<T extends Record<string, unknown>>(left: T): <U extends Record<string, unknown>>(right: U) => T & U;
1986
+ declare function mergeDeep<T extends Record<string, unknown>, U extends Record<string, unknown>>(left: T, right: U): T & U;
1987
+ type Evolver<T> = {
1988
+ [K in keyof T]?: T[K] extends Record<string, unknown> ? Evolver<T[K]> | ((val: T[K]) => T[K]) : (val: T[K]) => T[K];
1989
+ };
1990
+ declare function evolve<T extends Record<string, unknown>>(spec: Evolver<T>): (obj: T) => T;
1991
+ declare function evolve<T extends Record<string, unknown>>(spec: Evolver<T>, obj: T): T;
1992
+ type SpecValue = ((...args: any[]) => any) | {
1993
+ [key: string]: SpecValue;
1994
+ };
1995
+ declare function applySpec<R extends Record<string, any>>(spec: {
1996
+ [K in keyof R]: SpecValue;
1997
+ }): (...args: unknown[]) => R;
1998
+ type ExtendSpec = Record<string, (obj: any) => unknown>;
1999
+ /**
2000
+ * Extends an object with computed properties.
2001
+ *
2002
+ * Unlike `evolve` which transforms existing properties,
2003
+ * `extend` adds NEW properties computed from the object.
2004
+ *
2005
+ * @example
2006
+ * ```ts
2007
+ * const user = { first: 'John', last: 'Doe', age: 25 };
2008
+ *
2009
+ * extend({
2010
+ * fullName: ctx => `${ctx.first} ${ctx.last}`,
2011
+ * isAdult: ctx => ctx.age >= 18
2012
+ * }, user);
2013
+ * // { first: 'John', last: 'Doe', age: 25, fullName: 'John Doe', isAdult: true }
2014
+ *
2015
+ * // Curried
2016
+ * const withFullName = extend({
2017
+ * fullName: ctx => `${ctx.first} ${ctx.last}`
2018
+ * });
2019
+ * withFullName(user);
2020
+ * ```
2021
+ */
2022
+ declare function extend<S extends ExtendSpec>(spec: S): <T extends Record<string, unknown>>(obj: T) => T & {
2023
+ [K in keyof S]: ReturnType<S[K]>;
2024
+ };
2025
+ declare function extend<T extends Record<string, unknown>, S extends ExtendSpec>(spec: S, obj: T): T & {
2026
+ [K in keyof S]: ReturnType<S[K]>;
2027
+ };
2028
+
2029
+ /**
2030
+ * Object conversion operators
2031
+ * @module object/conversion
2032
+ */
2033
+ declare function keys<T extends Record<string, unknown>>(obj: T): (keyof T)[];
2034
+ declare function values<T extends Record<string, unknown>>(obj: T): T[keyof T][];
2035
+ declare function entries<T extends Record<string, unknown>>(obj: T): [keyof T, T[keyof T]][];
2036
+ declare function fromEntries<K extends string | number | symbol, V>(pairs: readonly (readonly [K, V])[]): Record<K, V>;
2037
+
2038
+ /**
2039
+ * Comparison operators
2040
+ * @module logic/comparison
2041
+ */
2042
+ declare function equals<T>(a: T): (b: T) => boolean;
2043
+ declare function equals<T>(a: T, b: T): boolean;
2044
+ declare function identical<T>(a: T): (b: T) => boolean;
2045
+ declare function identical<T>(a: T, b: T): boolean;
2046
+ declare function gt(a: number): (b: number) => boolean;
2047
+ declare function gt(a: number, b: number): boolean;
2048
+ declare function gte(a: number): (b: number) => boolean;
2049
+ declare function gte(a: number, b: number): boolean;
2050
+ declare function lt(a: number): (b: number) => boolean;
2051
+ declare function lt(a: number, b: number): boolean;
2052
+ declare function lte(a: number): (b: number) => boolean;
2053
+ declare function lte(a: number, b: number): boolean;
2054
+
2055
+ /**
2056
+ * Boolean logic operators
2057
+ * @module logic/boolean
2058
+ */
2059
+ type SimplePredicate$2<T> = (value: T) => boolean;
2060
+ declare function not(value: unknown): boolean;
2061
+ declare function and<T>(a: T): <U>(b: U) => T | U;
2062
+ declare function and<T, U>(a: T, b: U): T | U;
2063
+ declare function or<T>(a: T): <U>(b: U) => T | U;
2064
+ declare function or<T, U>(a: T, b: U): T | U;
2065
+ declare function both<T>(pred1: SimplePredicate$2<T>): (pred2: SimplePredicate$2<T>) => SimplePredicate$2<T>;
2066
+ declare function both<T>(pred1: SimplePredicate$2<T>, pred2: SimplePredicate$2<T>): SimplePredicate$2<T>;
2067
+ declare function either<T>(pred1: SimplePredicate$2<T>): (pred2: SimplePredicate$2<T>) => SimplePredicate$2<T>;
2068
+ declare function either<T>(pred1: SimplePredicate$2<T>, pred2: SimplePredicate$2<T>): SimplePredicate$2<T>;
2069
+ declare function complement<T>(pred: SimplePredicate$2<T>): SimplePredicate$2<T>;
2070
+ declare function allPass<T>(preds: readonly SimplePredicate$2<T>[]): SimplePredicate$2<T>;
2071
+ declare function anyPass<T>(preds: readonly SimplePredicate$2<T>[]): SimplePredicate$2<T>;
2072
+
2073
+ /**
2074
+ * Branching operators
2075
+ * @module logic/branching
2076
+ */
2077
+ type SimplePredicate$1<T> = (value: T) => boolean;
2078
+ declare function ifElse<T, R1, R2>(predicate: SimplePredicate$1<T>, onTrue: (value: T) => R1, onFalse: (value: T) => R2): (value: T) => R1 | R2;
2079
+ declare function when<T, R>(predicate: SimplePredicate$1<T>, transform: (value: T) => R): (value: T) => T | R;
2080
+ declare function unless<T, R>(predicate: SimplePredicate$1<T>, transform: (value: T) => R): (value: T) => T | R;
2081
+ type CondPair<T, R> = readonly [SimplePredicate$1<T>, (value: T) => R];
2082
+ declare function cond<T, R>(pairs: readonly CondPair<T, R>[]): (value: T) => R | undefined;
2083
+ declare function tryCatch<T, R, E>(tryer: (value: T) => R, catcher: (error: unknown, value: T) => E): (value: T) => R | E;
2084
+
2085
+ /**
2086
+ * Object predicate operators
2087
+ * @module logic/predicates
2088
+ */
2089
+ type SimplePredicate<T> = (value: T) => boolean;
2090
+ declare function propEq<K extends string>(key: K): {
2091
+ <V>(value: V): (obj: Record<K, unknown>) => boolean;
2092
+ <V>(value: V, obj: Record<K, unknown>): boolean;
2093
+ };
2094
+ declare function propEq<K extends string, V>(key: K, value: V): (obj: Record<K, unknown>) => boolean;
2095
+ declare function propEq<K extends string, V>(key: K, value: V, obj: Record<K, unknown>): boolean;
2096
+ declare function propSatisfies<T>(pred: SimplePredicate<T>): {
2097
+ <K extends string>(key: K): (obj: Record<K, T>) => boolean;
2098
+ <K extends string>(key: K, obj: Record<K, T>): boolean;
2099
+ };
2100
+ declare function propSatisfies<T, K extends string>(pred: SimplePredicate<T>, key: K): (obj: Record<K, T>) => boolean;
2101
+ declare function propSatisfies<T, K extends string>(pred: SimplePredicate<T>, key: K, obj: Record<K, T>): boolean;
2102
+ declare function pathEq(keys: readonly (string | number)[]): {
2103
+ <V>(value: V): (obj: unknown) => boolean;
2104
+ <V>(value: V, obj: unknown): boolean;
2105
+ };
2106
+ declare function pathEq<V>(keys: readonly (string | number)[], value: V): (obj: unknown) => boolean;
2107
+ declare function pathEq<V>(keys: readonly (string | number)[], value: V, obj: unknown): boolean;
2108
+ declare function pathSatisfies<T>(pred: SimplePredicate<T>): {
2109
+ (keys: readonly (string | number)[]): (obj: unknown) => boolean;
2110
+ (keys: readonly (string | number)[], obj: unknown): boolean;
2111
+ };
2112
+ declare function pathSatisfies<T>(pred: SimplePredicate<T>, keys: readonly (string | number)[]): (obj: unknown) => boolean;
2113
+ declare function pathSatisfies<T>(pred: SimplePredicate<T>, keys: readonly (string | number)[], obj: unknown): boolean;
2114
+ type WhereSpec<T> = {
2115
+ [K in keyof T]?: SimplePredicate<T[K]>;
2116
+ };
2117
+ declare function where<T extends Record<string, unknown>>(spec: WhereSpec<T>): (obj: T) => boolean;
2118
+ declare function where<T extends Record<string, unknown>>(spec: WhereSpec<T>, obj: T): boolean;
2119
+ type WhereEqSpec<T> = {
2120
+ [K in keyof T]?: T[K];
2121
+ };
2122
+ declare function whereEq<T extends Record<string, unknown>>(spec: WhereEqSpec<T>): (obj: T) => boolean;
2123
+ declare function whereEq<T extends Record<string, unknown>>(spec: WhereEqSpec<T>, obj: T): boolean;
2124
+
2125
+ /**
2126
+ * Type checking operators
2127
+ * @module logic/typecheck
2128
+ */
2129
+ type Constructor<T = unknown> = new (...args: any[]) => T;
2130
+ declare function is<T>(ctor: Constructor<T>): (value: unknown) => value is T;
2131
+ declare function is<T>(ctor: Constructor<T>, value: unknown): value is T;
2132
+ declare function isNil(value: unknown): value is null | undefined;
2133
+ declare function isNotNil<T>(value: T | null | undefined): value is T;
2134
+ declare function isEmpty(value: unknown): boolean;
2135
+ declare function isNotEmpty<T>(value: T): boolean;
2136
+
2137
+ /**
2138
+ * Nullish handling operators
2139
+ * @module logic/nullish
2140
+ */
2141
+ declare function defaultTo<D>(defaultValue: D): <T>(value: T | null | undefined) => T | D;
2142
+ declare function defaultTo<D, T>(defaultValue: D, value: T | null | undefined): T | D;
2143
+ declare function coalesce<T>(...values: readonly (T | null | undefined)[]): T | undefined;
2144
+
2145
+ /**
2146
+ * Math operators
2147
+ * @module math
2148
+ */
2149
+ declare function add(a: number): (b: number) => number;
2150
+ declare function add(a: number, b: number): number;
2151
+ declare function subtract(a: number): (b: number) => number;
2152
+ declare function subtract(a: number, b: number): number;
2153
+ declare function multiply(a: number): (b: number) => number;
2154
+ declare function multiply(a: number, b: number): number;
2155
+ declare function divide(a: number): (b: number) => number;
2156
+ declare function divide(a: number, b: number): number;
2157
+ declare function modulo(a: number): (b: number) => number;
2158
+ declare function modulo(a: number, b: number): number;
2159
+ declare function negate(n: number): number;
2160
+ declare function inc(n: number): number;
2161
+ declare function dec(n: number): number;
2162
+ declare function clamp(min: number, max: number): (value: number) => number;
2163
+ declare function clamp(min: number, max: number, value: number): number;
2164
+ declare function abs(n: number): number;
2165
+ declare function round(n: number): number;
2166
+ declare function floor(n: number): number;
2167
+ declare function ceil(n: number): number;
2168
+ declare function pow(exponent: number): (base: number) => number;
2169
+ declare function pow(exponent: number, base: number): number;
2170
+
2171
+ /**
2172
+ * String operators
2173
+ * @module string
2174
+ */
2175
+ declare function toUpper(str: string): string;
2176
+ declare function toLower(str: string): string;
2177
+ declare function trim(str: string): string;
2178
+ declare function split(separator: string | RegExp): (str: string) => string[];
2179
+ declare function split(separator: string | RegExp, str: string): string[];
2180
+ declare function join(separator: string): (arr: readonly string[]) => string;
2181
+ declare function join(separator: string, arr: readonly string[]): string;
2182
+ declare function replace(pattern: string | RegExp, replacement: string): (str: string) => string;
2183
+ declare function replace(pattern: string | RegExp, replacement: string, str: string): string;
2184
+ declare function startsWith(prefix: string): (str: string) => boolean;
2185
+ declare function startsWith(prefix: string, str: string): boolean;
2186
+ declare function endsWith(suffix: string): (str: string) => boolean;
2187
+ declare function endsWith(suffix: string, str: string): boolean;
2188
+ declare function test(pattern: RegExp): (str: string) => boolean;
2189
+ declare function test(pattern: RegExp, str: string): boolean;
2190
+ declare function match(pattern: RegExp): (str: string) => RegExpMatchArray | null;
2191
+ declare function match(pattern: RegExp, str: string): RegExpMatchArray | null;
2192
+ declare function substring(start: number, end?: number): (str: string) => string;
2193
+ declare function substring(start: number, end: number | undefined, str: string): string;
2194
+ declare function padStart(targetLength: number, padString?: string): (str: string) => string;
2195
+ declare function padStart(targetLength: number, padString: string | undefined, str: string): string;
2196
+ declare function padEnd(targetLength: number, padString?: string): (str: string) => string;
2197
+ declare function padEnd(targetLength: number, padString: string | undefined, str: string): string;
2198
+ declare function concatStr(a: string): (b: string) => string;
2199
+ declare function concatStr(a: string, b: string): string;
2200
+
2201
+ /**
2202
+ * Type coercion operators
2203
+ * @module type
2204
+ */
2205
+ declare function toString(value: unknown): string;
2206
+ declare function toNumber(value: unknown): number;
2207
+ declare function toBoolean(value: unknown): boolean;
2208
+ declare function toArray<T>(value: T | readonly T[] | Iterable<T>): T[];
2209
+ declare function toObject<T>(value: T): object;
2210
+ declare function type(value: unknown): string;
2211
+
2212
+ /**
2213
+ * Lens operators - Functional getters/setters for immutable data
2214
+ * @module advanced/lens
2215
+ */
2216
+ /**
2217
+ * A Lens is a pair of functions: a getter and a setter
2218
+ * - getter: (obj) => value - extracts a value from the structure
2219
+ * - setter: (value, obj) => obj - returns a new structure with the value updated
2220
+ */
2221
+ interface Lens<S, A> {
2222
+ /** Get the focused value from the structure */
2223
+ get: (obj: S) => A;
2224
+ /** Set a new value, returning a new structure */
2225
+ set: (val: A, obj: S) => S;
2226
+ }
2227
+ /**
2228
+ * Creates a lens from a getter and setter function
2229
+ */
2230
+ declare function lens<S, A>(getter: (obj: S) => A, setter: (val: A, obj: S) => S): Lens<S, A>;
2231
+ /**
2232
+ * Creates a lens focused on a property of an object
2233
+ */
2234
+ declare function lensProp<S extends object, K extends keyof S>(key: K): Lens<S, S[K]>;
2235
+ /**
2236
+ * Creates a lens focused on a nested path in an object
2237
+ */
2238
+ declare function lensPath<S = unknown, A = unknown>(keys: readonly (string | number)[]): Lens<S, A>;
2239
+ /**
2240
+ * Creates a lens focused on an index in an array
2241
+ */
2242
+ declare function lensIndex<A>(index: number): Lens<readonly A[], A>;
2243
+ /**
2244
+ * Returns the value focused by the lens
2245
+ */
2246
+ declare function view<S, A>(lens: Lens<S, A>): (obj: S) => A;
2247
+ declare function view<S, A>(lens: Lens<S, A>, obj: S): A;
2248
+ /**
2249
+ * Sets the value focused by the lens, returning a new structure
2250
+ */
2251
+ declare function set<S, A>(lens: Lens<S, A>): {
2252
+ (val: A): (obj: S) => S;
2253
+ (val: A, obj: S): S;
2254
+ };
2255
+ declare function set<S, A>(lens: Lens<S, A>, val: A): (obj: S) => S;
2256
+ declare function set<S, A>(lens: Lens<S, A>, val: A, obj: S): S;
2257
+ /**
2258
+ * Applies a function to the value focused by the lens, returning a new structure
2259
+ */
2260
+ declare function over<S, A>(lens: Lens<S, A>): {
2261
+ (fn: (val: A) => A): (obj: S) => S;
2262
+ (fn: (val: A) => A, obj: S): S;
2263
+ };
2264
+ declare function over<S, A>(lens: Lens<S, A>, fn: (val: A) => A): (obj: S) => S;
2265
+ declare function over<S, A>(lens: Lens<S, A>, fn: (val: A) => A, obj: S): S;
2266
+
2267
+ /**
2268
+ * Async operators - Asynchronous array operations
2269
+ * @module advanced/async
2270
+ */
2271
+ /**
2272
+ * Maps over an array with an async function, executing in parallel
2273
+ * All promises are started simultaneously and results are awaited together
2274
+ */
2275
+ declare function mapAsync<T, U>(fn: (value: T, index: number) => Promise<U>): (arr: readonly T[]) => Promise<U[]>;
2276
+ declare function mapAsync<T, U>(fn: (value: T, index: number) => Promise<U>, arr: readonly T[]): Promise<U[]>;
2277
+ /**
2278
+ * Maps over an array with an async function, executing sequentially
2279
+ * Each promise must complete before the next one starts
2280
+ */
2281
+ declare function mapSerial<T, U>(fn: (value: T, index: number) => Promise<U>): (arr: readonly T[]) => Promise<U[]>;
2282
+ declare function mapSerial<T, U>(fn: (value: T, index: number) => Promise<U>, arr: readonly T[]): Promise<U[]>;
2283
+ /**
2284
+ * Filters an array with an async predicate, executing in parallel
2285
+ */
2286
+ declare function filterAsync<T>(predicate: (value: T, index: number) => Promise<boolean>): (arr: readonly T[]) => Promise<T[]>;
2287
+ declare function filterAsync<T>(predicate: (value: T, index: number) => Promise<boolean>, arr: readonly T[]): Promise<T[]>;
2288
+ /**
2289
+ * Reduces an array with an async reducer, executing sequentially
2290
+ */
2291
+ declare function reduceAsync<T, U>(fn: (acc: U, value: T, index: number) => Promise<U>, initial: U): (arr: readonly T[]) => Promise<U>;
2292
+ declare function reduceAsync<T, U>(fn: (acc: U, value: T, index: number) => Promise<U>, initial: U, arr: readonly T[]): Promise<U>;
2293
+
2294
+ /**
2295
+ * Transducer operators - Composable algorithmic transformations
2296
+ * @module advanced/transducer
2297
+ *
2298
+ * Transducers are composable higher-order reducers that can be used to
2299
+ * transform data without creating intermediate collections.
2300
+ */
2301
+ /**
2302
+ * Transducer protocol symbols
2303
+ */
2304
+ declare const TRANSDUCER_INIT = "@@transducer/init";
2305
+ declare const TRANSDUCER_STEP = "@@transducer/step";
2306
+ declare const TRANSDUCER_RESULT = "@@transducer/result";
2307
+ /**
2308
+ * A Transformer implements the transducer protocol
2309
+ */
2310
+ interface Transformer<Acc, Input> {
2311
+ [TRANSDUCER_INIT]: () => Acc;
2312
+ [TRANSDUCER_STEP]: (acc: Acc, input: Input) => Acc;
2313
+ [TRANSDUCER_RESULT]: (acc: Acc) => Acc;
2314
+ }
2315
+ /**
2316
+ * A Transducer transforms one transformer into another
2317
+ */
2318
+ type Transducer<A, B> = <Acc>(xf: Transformer<Acc, B>) => Transformer<Acc, A>;
2319
+ /**
2320
+ * Creates a mapping transducer
2321
+ */
2322
+ declare function mapT<A, B>(fn: (val: A) => B): Transducer<A, B>;
2323
+ /**
2324
+ * Creates a filtering transducer
2325
+ */
2326
+ declare function filterT<A>(pred: (val: A) => boolean): Transducer<A, A>;
2327
+ /**
2328
+ * Creates a take transducer that takes the first n items
2329
+ */
2330
+ declare function takeT<A>(n: number): Transducer<A, A>;
2331
+ /**
2332
+ * Creates a drop transducer that skips the first n items
2333
+ */
2334
+ declare function dropT<A>(n: number): Transducer<A, A>;
2335
+ /**
2336
+ * Composes transducers from left to right
2337
+ */
2338
+ declare function composeT<A, B, C>(t1: Transducer<A, B>, t2: Transducer<B, C>): Transducer<A, C>;
2339
+ declare function composeT<A, B, C, D>(t1: Transducer<A, B>, t2: Transducer<B, C>, t3: Transducer<C, D>): Transducer<A, D>;
2340
+ declare function composeT<A, B, C, D, E>(t1: Transducer<A, B>, t2: Transducer<B, C>, t3: Transducer<C, D>, t4: Transducer<D, E>): Transducer<A, E>;
2341
+ /**
2342
+ * Applies a transducer to a collection using a transformer
2343
+ */
2344
+ declare function transduce<A, B, Acc>(transducer: Transducer<A, B>, transformer: Transformer<Acc, B>, initial: Acc, collection: readonly A[]): Acc;
2345
+ declare function transduce<A, B, Acc>(transducer: Transducer<A, B>, transformer: Transformer<Acc, B>, initial: Acc): (collection: readonly A[]) => Acc;
2346
+ /**
2347
+ * Applies a transducer to a collection, outputting to an array
2348
+ * Shorthand for transduce with array transformer
2349
+ */
2350
+ declare function into<A, B>(transducer: Transducer<A, B>): (collection: readonly A[]) => B[];
2351
+ declare function into<A, B>(transducer: Transducer<A, B>, collection: readonly A[]): B[];
2352
+
2353
+ export { type BinaryFn, type Comparator, type ComposeBuilderFn, type Curry1, type Curry2, type Curry3, type DeepReadonly, F, type Fn, type Head, type Last, type Lens, type Mapper, type Nullable, type ParamsOf, type PipeBuilderFn, type PipeFn, type PipeTransformer, type Placeholder, type Predicate, type Reducer, type ReturnOf, T$1 as T, TRANSDUCER_INIT, TRANSDUCER_RESULT, TRANSDUCER_STEP, type Tail, type TernaryFn, type Transducer, type Transformer, type UnaryFn, type VariadicFn, placeholder as __, abs, add, allPass, always, and, anyPass, append, applySpec, assoc, assocPath, both, ceil, chain, clamp, coalesce, complement, compose, composeAsync, composeK, composeT, concat, concatStr, cond, countBy, curry, curryN, dec, defaultTo, dissoc, dissocPath, divide, drop, dropLast, dropT, dropWhile, either, endsWith, entries, equals, every, evolve, extend, filter, filterAsync, filterT, find, findIndex, findLast, flatten, floor, fromEntries, groupBy, gt, gte, head, identical, identity, ifElse, inc, includes, indexBy, indexOf, init, into, is, isEmpty, isNil, isNotEmpty, isNotNil, isPlaceholder, join, keys, last, length, lens, lensIndex, lensPath, lensProp, letIn, lt, lte, map, mapAsync, mapSerial, mapT, match, max, mean, median, merge, mergeDeep, min, modulo, multiply, negate, none, not, nth, omit, or, over, padEnd, padStart, partial, partialRight, partition, path, pathEq, pathOr, pathSatisfies, pick, pipe, pipeAsync, pipeBuilder, pipeK, pipeWith, pluck, pow, prepend, product, prop, propEq, propOr, propSatisfies, props, range, reduce, reduceAsync, reduceRight, reject, replace, reverse, round, set, slice, some, sort, sortBy, split, splitEvery, startsWith, substring, subtract, sum, tail, take, takeLast, takeT, takeWhile, tap, test, toArray, toBoolean, toLower, toNumber, toObject, toString, toUpper, transduce, trim, tryCatch, type, uniq, uniqBy, unless, unnest, values, view, when, where, whereEq, zip, zipObj, zipWith };