fp-pack 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -15
- package/dist/fp-pack.umd.js +1 -1
- package/dist/fp-pack.umd.js.map +1 -1
- package/dist/implement/async/pipeAsync.d.ts +11 -0
- package/dist/implement/async/pipeAsync.d.ts.map +1 -1
- package/dist/implement/async/pipeAsync.mjs.map +1 -1
- package/dist/implement/async/pipeAsyncSideEffect.d.ts +11 -0
- package/dist/implement/async/pipeAsyncSideEffect.d.ts.map +1 -1
- package/dist/implement/async/pipeAsyncSideEffect.mjs.map +1 -1
- package/dist/implement/composition/compose.d.ts +25 -9
- package/dist/implement/composition/compose.d.ts.map +1 -1
- package/dist/implement/composition/compose.mjs.map +1 -1
- package/dist/implement/composition/compose.type-test.d.ts +35 -0
- package/dist/implement/composition/compose.type-test.d.ts.map +1 -0
- package/dist/implement/composition/compose.util.type-test.d.ts +31 -0
- package/dist/implement/composition/compose.util.type-test.d.ts.map +1 -0
- package/dist/implement/composition/curry.d.ts +5 -5
- package/dist/implement/composition/curry.d.ts.map +1 -1
- package/dist/implement/composition/curry.mjs.map +1 -1
- package/dist/implement/composition/index.d.ts +4 -0
- package/dist/implement/composition/index.d.ts.map +1 -1
- package/dist/implement/composition/pipe.d.ts +3 -0
- package/dist/implement/composition/pipe.d.ts.map +1 -1
- package/dist/implement/composition/pipe.mjs.map +1 -1
- package/dist/implement/composition/pipe.type-test.d.ts +117 -1
- package/dist/implement/composition/pipe.type-test.d.ts.map +1 -1
- package/dist/implement/composition/pipe.util.type-test.d.ts +75 -0
- package/dist/implement/composition/pipe.util.type-test.d.ts.map +1 -0
- package/dist/implement/composition/sideEffect.d.ts +1 -1
- package/dist/implement/composition/sideEffect.d.ts.map +1 -1
- package/dist/implement/composition/sideEffect.mjs.map +1 -1
- package/dist/implement/composition/tap0.d.ts +6 -0
- package/dist/implement/composition/tap0.d.ts.map +1 -0
- package/dist/implement/composition/tap0.mjs +9 -0
- package/dist/implement/composition/tap0.mjs.map +1 -0
- package/dist/implement/object/assocPath.d.ts +2 -1
- package/dist/implement/object/assocPath.d.ts.map +1 -1
- package/dist/implement/object/assocPath.mjs.map +1 -1
- package/dist/implement/object/dissocPath.d.ts +2 -1
- package/dist/implement/object/dissocPath.d.ts.map +1 -1
- package/dist/implement/object/dissocPath.mjs.map +1 -1
- package/dist/implement/object/index.d.ts +1 -0
- package/dist/implement/object/index.d.ts.map +1 -1
- package/dist/implement/object/path.d.ts +4 -2
- package/dist/implement/object/path.d.ts.map +1 -1
- package/dist/implement/object/path.mjs.map +1 -1
- package/dist/implement/object/pathKey.d.ts +2 -0
- package/dist/implement/object/pathKey.d.ts.map +1 -0
- package/dist/implement/object/pathOr.d.ts +5 -3
- package/dist/implement/object/pathOr.d.ts.map +1 -1
- package/dist/implement/object/pathOr.mjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +230 -228
- package/dist/index.mjs.map +1 -1
- package/dist/skills/fp-pack/SKILL.md +19 -16
- package/dist/skills/fp-pack.md +19 -16
- package/dist/stream/index.d.ts +1 -0
- package/dist/stream/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/implement/async/pipeAsync.ts +71 -0
- package/src/implement/async/pipeAsyncSideEffect.ts +74 -0
- package/src/implement/composition/compose.test.ts +14 -0
- package/src/implement/composition/compose.ts +133 -21
- package/src/implement/composition/compose.type-test.ts +109 -0
- package/src/implement/composition/compose.util.type-test.ts +128 -0
- package/src/implement/composition/curry.ts +5 -5
- package/src/implement/composition/index.ts +4 -0
- package/src/implement/composition/pipe.ts +4 -0
- package/src/implement/composition/pipe.type-test.ts +269 -1
- package/src/implement/composition/pipe.util.type-test.ts +256 -0
- package/src/implement/composition/sideEffect.ts +1 -1
- package/src/implement/composition/tap0.test.ts +16 -0
- package/src/implement/composition/tap0.ts +10 -0
- package/src/implement/object/assocPath.ts +2 -2
- package/src/implement/object/dissocPath.ts +2 -2
- package/src/implement/object/index.ts +1 -0
- package/src/implement/object/path.ts +5 -3
- package/src/implement/object/pathKey.ts +1 -0
- package/src/implement/object/pathOr.ts +6 -4
- package/src/index.ts +3 -0
- package/src/stream/index.ts +1 -0
|
@@ -7,7 +7,7 @@ metadata:
|
|
|
7
7
|
|
|
8
8
|
# fp-pack AI Agent Skills
|
|
9
9
|
|
|
10
|
-
Document Version: 0.
|
|
10
|
+
Document Version: 0.7.0
|
|
11
11
|
|
|
12
12
|
This document provides guidelines for AI coding assistants when working in projects that use fp-pack. Follow these instructions to write clean, declarative, functional code using fp-pack's utilities.
|
|
13
13
|
|
|
@@ -129,7 +129,7 @@ const finalValue = runPipeResult(processDataPipeline(input));
|
|
|
129
129
|
**Key SideEffect functions:**
|
|
130
130
|
- `SideEffect.of(fn, label?)` - Create a side effect container
|
|
131
131
|
- `isSideEffect(value)` - Type guard for **runtime checking** whether a value is a SideEffect
|
|
132
|
-
- `runPipeResult<T, R>(result)` - Execute SideEffect or return value (call **OUTSIDE** pipelines
|
|
132
|
+
- `runPipeResult<T, R>(result)` - Execute SideEffect or return value (call **OUTSIDE** pipelines). If the input type is precise, inference is preserved. If the input is widened to `SideEffect<any>` or `any`, the result becomes `any` unless you provide generics.
|
|
133
133
|
- `matchSideEffect(result, { value, effect })` - Pattern match on result
|
|
134
134
|
|
|
135
135
|
**Type-safe result handling:**
|
|
@@ -147,32 +147,34 @@ const processNumbers = pipeSideEffect(
|
|
|
147
147
|
|
|
148
148
|
const result = processNumbers([1, 2, 3, 4, 5]);
|
|
149
149
|
|
|
150
|
-
// ✅ CORRECT: Use isSideEffect for runtime checking
|
|
150
|
+
// ✅ CORRECT: Use isSideEffect for runtime checking
|
|
151
151
|
if (!isSideEffect(result)) {
|
|
152
152
|
// TypeScript knows: result is number[]
|
|
153
153
|
const sum: number = result.reduce((a, b) => a + b, 0);
|
|
154
154
|
} else {
|
|
155
155
|
// TypeScript knows: result is SideEffect<string>
|
|
156
|
-
//
|
|
157
|
-
const error = runPipeResult
|
|
156
|
+
// runPipeResult returns number[] | string (not fully narrowed)
|
|
157
|
+
const error = runPipeResult(result); // number[] | string
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
//
|
|
161
|
-
const
|
|
160
|
+
// ⚠️ If the result type is widened to SideEffect<any>, inference is lost
|
|
161
|
+
const widened: number[] | SideEffect<any> = result;
|
|
162
|
+
const unsafeValue = runPipeResult(widened); // number[] | any
|
|
162
163
|
|
|
163
|
-
// ✅ CORRECT: Provide generics to
|
|
164
|
-
const
|
|
164
|
+
// ✅ CORRECT: Provide generics to recover a safe union
|
|
165
|
+
const safeValue = runPipeResult<number[], string>(result); // result: number[] | string (union type - safe but not narrowed)
|
|
165
166
|
```
|
|
166
167
|
|
|
167
168
|
**⚠️ CRITICAL: runPipeResult Type Safety**
|
|
168
169
|
|
|
169
170
|
`runPipeResult<T, R=any>` has a default type parameter `R=any`. This means:
|
|
170
171
|
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
- ✅ **With
|
|
172
|
+
- ✅ **Precise input types**: `T | SideEffect<'E'>` preserves `T | 'E'` without extra annotations.
|
|
173
|
+
- ⚠️ **Widened inputs**: `T | SideEffect<any>` (or `any`) collapses to `any`.
|
|
174
|
+
- ✅ **With generics**: `runPipeResult<SuccessType, ErrorType>(result)` restores a safe union when inference is lost.
|
|
175
|
+
- ✅ **With isSideEffect**: Prefer for runtime narrowing when you need branch-specific types.
|
|
174
176
|
|
|
175
|
-
|
|
177
|
+
Provide generics when inference is lost; prefer `isSideEffect` for precise narrowing.
|
|
176
178
|
|
|
177
179
|
## Stream Functions - Lazy Iterable Processing
|
|
178
180
|
|
|
@@ -219,6 +221,7 @@ const result = Array.from({ length: 1000000 }, (_, i) => i + 1)
|
|
|
219
221
|
- `constant` - Always return the same value
|
|
220
222
|
- `from` - Ignore input and return a fixed value
|
|
221
223
|
- `tap` - Execute side effect and return original value
|
|
224
|
+
- `tap0` - Execute side effect without input
|
|
222
225
|
- `once` - Execute function only once
|
|
223
226
|
- `memoize` - Cache function results
|
|
224
227
|
- `SideEffect` - Side effect container
|
|
@@ -527,7 +530,7 @@ const gradeToLetter = cond([
|
|
|
527
530
|
|
|
528
531
|
- `prop` returns `T[K] | undefined`. Use `propOr` (or guard) before array operations.
|
|
529
532
|
- `ifElse` expects **functions** for both branches. If you already have a value, wrap it: `() => value` or use `from(value)` for cleaner constant branches.
|
|
530
|
-
- Use `from(value)` when you need a unary function that ignores input (handy for `ifElse`/`cond` branches and data-first patterns).
|
|
533
|
+
- Use `from(value)` when you need a unary function that ignores input (handy for `ifElse`/`cond` branches and data-first patterns). Pipelines that start with `from(...)` can be called without an initial input value.
|
|
531
534
|
- `cond` returns `R | undefined`. Add a default branch and coalesce when you need a strict result.
|
|
532
535
|
- In `pipeSideEffect`, keep step return types aligned to avoid wide unions.
|
|
533
536
|
|
|
@@ -680,8 +683,8 @@ const updateUser = assoc('lastLogin', new Date());
|
|
|
680
683
|
- **Pure async operations**: `pipeAsync`
|
|
681
684
|
- **Error handling with SideEffect**: `pipeSideEffect` (sync) / `pipeAsyncSideEffect` (async)
|
|
682
685
|
- **Strict SideEffect unions**: `pipeSideEffectStrict` (sync) / `pipeAsyncSideEffectStrict` (async)
|
|
683
|
-
- **Type-safe result handling**: `isSideEffect` for precise type narrowing (
|
|
684
|
-
- **Execute SideEffect**: `runPipeResult` (call OUTSIDE pipelines).
|
|
686
|
+
- **Type-safe result handling**: `isSideEffect` for precise type narrowing (prefer this when you need branch-specific types)
|
|
687
|
+
- **Execute SideEffect**: `runPipeResult` (call OUTSIDE pipelines). If the input is widened to `SideEffect<any>`/`any`, the result becomes `any`; provide generics to recover
|
|
685
688
|
- **Large datasets**: `stream/*` functions
|
|
686
689
|
- **Conditionals**: `ifElse`, `when`, `unless`, `cond`
|
|
687
690
|
- **Object access**: `prop`, `propStrict`, `path`, `pick`, `omit`
|
package/dist/skills/fp-pack.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# fp-pack AI Agent Skills
|
|
2
2
|
|
|
3
|
-
Document Version: 0.
|
|
3
|
+
Document Version: 0.7.0
|
|
4
4
|
|
|
5
5
|
This document provides guidelines for AI coding assistants when working in projects that use fp-pack. Follow these instructions to write clean, declarative, functional code using fp-pack's utilities.
|
|
6
6
|
|
|
@@ -122,7 +122,7 @@ const finalValue = runPipeResult(processDataPipeline(input));
|
|
|
122
122
|
**Key SideEffect functions:**
|
|
123
123
|
- `SideEffect.of(fn, label?)` - Create a side effect container
|
|
124
124
|
- `isSideEffect(value)` - Type guard for **runtime checking** whether a value is a SideEffect
|
|
125
|
-
- `runPipeResult<T, R>(result)` - Execute SideEffect or return value (call **OUTSIDE** pipelines
|
|
125
|
+
- `runPipeResult<T, R>(result)` - Execute SideEffect or return value (call **OUTSIDE** pipelines). If the input type is precise, inference is preserved. If the input is widened to `SideEffect<any>` or `any`, the result becomes `any` unless you provide generics.
|
|
126
126
|
- `matchSideEffect(result, { value, effect })` - Pattern match on result
|
|
127
127
|
|
|
128
128
|
**Type-safe result handling:**
|
|
@@ -140,32 +140,34 @@ const processNumbers = pipeSideEffect(
|
|
|
140
140
|
|
|
141
141
|
const result = processNumbers([1, 2, 3, 4, 5]);
|
|
142
142
|
|
|
143
|
-
// ✅ CORRECT: Use isSideEffect for runtime checking
|
|
143
|
+
// ✅ CORRECT: Use isSideEffect for runtime checking
|
|
144
144
|
if (!isSideEffect(result)) {
|
|
145
145
|
// TypeScript knows: result is number[]
|
|
146
146
|
const sum: number = result.reduce((a, b) => a + b, 0);
|
|
147
147
|
} else {
|
|
148
148
|
// TypeScript knows: result is SideEffect<string>
|
|
149
|
-
//
|
|
150
|
-
const error = runPipeResult
|
|
149
|
+
// runPipeResult returns number[] | string (not fully narrowed)
|
|
150
|
+
const error = runPipeResult(result); // number[] | string
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
//
|
|
154
|
-
const
|
|
153
|
+
// ⚠️ If the result type is widened to SideEffect<any>, inference is lost
|
|
154
|
+
const widened: number[] | SideEffect<any> = result;
|
|
155
|
+
const unsafeValue = runPipeResult(widened); // number[] | any
|
|
155
156
|
|
|
156
|
-
// ✅ CORRECT: Provide generics to
|
|
157
|
-
const
|
|
157
|
+
// ✅ CORRECT: Provide generics to recover a safe union
|
|
158
|
+
const safeValue = runPipeResult<number[], string>(result); // result: number[] | string (union type - safe but not narrowed)
|
|
158
159
|
```
|
|
159
160
|
|
|
160
161
|
**⚠️ CRITICAL: runPipeResult Type Safety**
|
|
161
162
|
|
|
162
163
|
`runPipeResult<T, R=any>` has a default type parameter `R=any`. This means:
|
|
163
164
|
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
- ✅ **With
|
|
165
|
+
- ✅ **Precise input types**: `T | SideEffect<'E'>` preserves `T | 'E'` without extra annotations.
|
|
166
|
+
- ⚠️ **Widened inputs**: `T | SideEffect<any>` (or `any`) collapses to `any`.
|
|
167
|
+
- ✅ **With generics**: `runPipeResult<SuccessType, ErrorType>(result)` restores a safe union when inference is lost.
|
|
168
|
+
- ✅ **With isSideEffect**: Prefer for runtime narrowing when you need branch-specific types.
|
|
167
169
|
|
|
168
|
-
|
|
170
|
+
Provide generics when inference is lost; prefer `isSideEffect` for precise narrowing.
|
|
169
171
|
|
|
170
172
|
## Stream Functions - Lazy Iterable Processing
|
|
171
173
|
|
|
@@ -212,6 +214,7 @@ const result = Array.from({ length: 1000000 }, (_, i) => i + 1)
|
|
|
212
214
|
- `constant` - Always return the same value
|
|
213
215
|
- `from` - Ignore input and return a fixed value
|
|
214
216
|
- `tap` - Execute side effect and return original value
|
|
217
|
+
- `tap0` - Execute side effect without input
|
|
215
218
|
- `once` - Execute function only once
|
|
216
219
|
- `memoize` - Cache function results
|
|
217
220
|
- `SideEffect` - Side effect container
|
|
@@ -520,7 +523,7 @@ const gradeToLetter = cond([
|
|
|
520
523
|
|
|
521
524
|
- `prop` returns `T[K] | undefined`. Use `propOr` (or guard) before array operations.
|
|
522
525
|
- `ifElse` expects **functions** for both branches. If you already have a value, wrap it: `() => value` or use `from(value)` for cleaner constant branches.
|
|
523
|
-
- Use `from(value)` when you need a unary function that ignores input (handy for `ifElse`/`cond` branches and data-first patterns).
|
|
526
|
+
- Use `from(value)` when you need a unary function that ignores input (handy for `ifElse`/`cond` branches and data-first patterns). Pipelines that start with `from(...)` can be called without an initial input value.
|
|
524
527
|
- `cond` returns `R | undefined`. Add a default branch and coalesce when you need a strict result.
|
|
525
528
|
- In `pipeSideEffect`, keep step return types aligned to avoid wide unions.
|
|
526
529
|
|
|
@@ -673,8 +676,8 @@ const updateUser = assoc('lastLogin', new Date());
|
|
|
673
676
|
- **Pure async operations**: `pipeAsync`
|
|
674
677
|
- **Error handling with SideEffect**: `pipeSideEffect` (sync) / `pipeAsyncSideEffect` (async)
|
|
675
678
|
- **Strict SideEffect unions**: `pipeSideEffectStrict` (sync) / `pipeAsyncSideEffectStrict` (async)
|
|
676
|
-
- **Type-safe result handling**: `isSideEffect` for precise type narrowing (
|
|
677
|
-
- **Execute SideEffect**: `runPipeResult` (call OUTSIDE pipelines).
|
|
679
|
+
- **Type-safe result handling**: `isSideEffect` for precise type narrowing (prefer this when you need branch-specific types)
|
|
680
|
+
- **Execute SideEffect**: `runPipeResult` (call OUTSIDE pipelines). If the input is widened to `SideEffect<any>`/`any`, the result becomes `any`; provide generics to recover
|
|
678
681
|
- **Large datasets**: `stream/*` functions
|
|
679
682
|
- **Conditionals**: `ifElse`, `when`, `unless`, `cond`
|
|
680
683
|
- **Object access**: `prop`, `propStrict`, `path`, `pick`, `omit`
|
package/dist/stream/index.d.ts
CHANGED
|
@@ -21,4 +21,5 @@ export { default as toArray } from './toArray';
|
|
|
21
21
|
export { default as toAsync } from './toAsync';
|
|
22
22
|
export { default as zip } from './zip';
|
|
23
23
|
export { default as zipWith } from './zipWith';
|
|
24
|
+
export type { AnyIterable, AnyIterableInput, PromiseLikeValue } from './utils';
|
|
24
25
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stream/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stream/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@ import type { FromFn } from '../composition/from';
|
|
|
2
2
|
|
|
3
3
|
/** pipeAsync - 비동기 함수 합성 */
|
|
4
4
|
type AsyncOrSync<A, R> = (a: A) => R | Promise<R>;
|
|
5
|
+
type ZeroFn<R> = () => R | Promise<R>;
|
|
5
6
|
type PipeInput<Fns extends AsyncOrSync<any, any>[]> = Fns extends [AsyncOrSync<infer A, any>, ...AsyncOrSync<any, any>[]]
|
|
6
7
|
? A
|
|
7
8
|
: never;
|
|
@@ -17,6 +18,76 @@ type PipeAsyncFrom<Fns extends [FromFn<any>, ...AsyncOrSync<any, any>[]]> = (
|
|
|
17
18
|
input?: PipeInput<Fns>
|
|
18
19
|
) => Promise<PipeOutput<Fns>>;
|
|
19
20
|
|
|
21
|
+
function pipeAsync<R>(ab: ZeroFn<R>): () => Promise<Awaited<R>>;
|
|
22
|
+
function pipeAsync<B, R>(ab: ZeroFn<B>, bc: AsyncOrSync<Awaited<B>, R>): () => Promise<Awaited<R>>;
|
|
23
|
+
function pipeAsync<B, C, R>(
|
|
24
|
+
ab: ZeroFn<B>,
|
|
25
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
26
|
+
cd: AsyncOrSync<Awaited<C>, R>
|
|
27
|
+
): () => Promise<Awaited<R>>;
|
|
28
|
+
function pipeAsync<B, C, D, R>(
|
|
29
|
+
ab: ZeroFn<B>,
|
|
30
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
31
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
32
|
+
de: AsyncOrSync<Awaited<D>, R>
|
|
33
|
+
): () => Promise<Awaited<R>>;
|
|
34
|
+
function pipeAsync<B, C, D, E, R>(
|
|
35
|
+
ab: ZeroFn<B>,
|
|
36
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
37
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
38
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
39
|
+
ef: AsyncOrSync<Awaited<E>, R>
|
|
40
|
+
): () => Promise<Awaited<R>>;
|
|
41
|
+
function pipeAsync<B, C, D, E, F, R>(
|
|
42
|
+
ab: ZeroFn<B>,
|
|
43
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
44
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
45
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
46
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
47
|
+
fg: AsyncOrSync<Awaited<F>, R>
|
|
48
|
+
): () => Promise<Awaited<R>>;
|
|
49
|
+
function pipeAsync<B, C, D, E, F, G, R>(
|
|
50
|
+
ab: ZeroFn<B>,
|
|
51
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
52
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
53
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
54
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
55
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
56
|
+
gh: AsyncOrSync<Awaited<G>, R>
|
|
57
|
+
): () => Promise<Awaited<R>>;
|
|
58
|
+
function pipeAsync<B, C, D, E, F, G, H, R>(
|
|
59
|
+
ab: ZeroFn<B>,
|
|
60
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
61
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
62
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
63
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
64
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
65
|
+
gh: AsyncOrSync<Awaited<G>, H>,
|
|
66
|
+
hi: AsyncOrSync<Awaited<H>, R>
|
|
67
|
+
): () => Promise<Awaited<R>>;
|
|
68
|
+
function pipeAsync<B, C, D, E, F, G, H, I, R>(
|
|
69
|
+
ab: ZeroFn<B>,
|
|
70
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
71
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
72
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
73
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
74
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
75
|
+
gh: AsyncOrSync<Awaited<G>, H>,
|
|
76
|
+
hi: AsyncOrSync<Awaited<H>, I>,
|
|
77
|
+
ij: AsyncOrSync<Awaited<I>, R>
|
|
78
|
+
): () => Promise<Awaited<R>>;
|
|
79
|
+
function pipeAsync<B, C, D, E, F, G, H, I, J, R>(
|
|
80
|
+
ab: ZeroFn<B>,
|
|
81
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
82
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
83
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
84
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
85
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
86
|
+
gh: AsyncOrSync<Awaited<G>, H>,
|
|
87
|
+
hi: AsyncOrSync<Awaited<H>, I>,
|
|
88
|
+
ij: AsyncOrSync<Awaited<I>, J>,
|
|
89
|
+
jk: AsyncOrSync<Awaited<J>, R>
|
|
90
|
+
): () => Promise<Awaited<R>>;
|
|
20
91
|
function pipeAsync<Fns extends [FromFn<any>, ...AsyncOrSync<any, any>[]]>(...funcs: Fns): PipeAsyncFrom<Fns>;
|
|
21
92
|
function pipeAsync<A, R>(ab: AsyncOrSync<A, R>): (a: A) => Promise<Awaited<R>>;
|
|
22
93
|
function pipeAsync<A, B, R>(ab: AsyncOrSync<A, B>, bc: AsyncOrSync<Awaited<B>, R>): (a: A) => Promise<Awaited<R>>;
|
|
@@ -5,6 +5,7 @@ import SideEffect, { isSideEffect } from '../composition/sideEffect';
|
|
|
5
5
|
type MaybeSideEffect<T> = T | SideEffect<any>;
|
|
6
6
|
type NonSideEffect<T> = Exclude<T, SideEffect<any>>;
|
|
7
7
|
type AsyncOrSync<A, R> = (a: A) => MaybeSideEffect<R> | Promise<MaybeSideEffect<R>>;
|
|
8
|
+
type ZeroFn<R> = () => MaybeSideEffect<R> | Promise<MaybeSideEffect<R>>;
|
|
8
9
|
type PipeInput<Fns extends AsyncOrSync<any, any>[]> = Fns extends [
|
|
9
10
|
AsyncOrSync<infer A, any>,
|
|
10
11
|
...AsyncOrSync<any, any>[]
|
|
@@ -29,6 +30,79 @@ type PipeAsyncSideEffectFrom<Fns extends [FromFn<any>, ...AsyncOrSync<any, any>[
|
|
|
29
30
|
function pipeAsyncSideEffect<Fns extends [FromFn<any>, ...AsyncOrSync<any, any>[]]>(
|
|
30
31
|
...funcs: Fns
|
|
31
32
|
): PipeAsyncSideEffectFrom<Fns>;
|
|
33
|
+
function pipeAsyncSideEffect<R>(ab: ZeroFn<R>): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
34
|
+
function pipeAsyncSideEffect<B, R>(
|
|
35
|
+
ab: ZeroFn<B>,
|
|
36
|
+
bc: AsyncOrSync<Awaited<B>, R>
|
|
37
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
38
|
+
function pipeAsyncSideEffect<B, C, R>(
|
|
39
|
+
ab: ZeroFn<B>,
|
|
40
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
41
|
+
cd: AsyncOrSync<Awaited<C>, R>
|
|
42
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
43
|
+
function pipeAsyncSideEffect<B, C, D, R>(
|
|
44
|
+
ab: ZeroFn<B>,
|
|
45
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
46
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
47
|
+
de: AsyncOrSync<Awaited<D>, R>
|
|
48
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
49
|
+
function pipeAsyncSideEffect<B, C, D, E, R>(
|
|
50
|
+
ab: ZeroFn<B>,
|
|
51
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
52
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
53
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
54
|
+
ef: AsyncOrSync<Awaited<E>, R>
|
|
55
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
56
|
+
function pipeAsyncSideEffect<B, C, D, E, F, R>(
|
|
57
|
+
ab: ZeroFn<B>,
|
|
58
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
59
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
60
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
61
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
62
|
+
fg: AsyncOrSync<Awaited<F>, R>
|
|
63
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
64
|
+
function pipeAsyncSideEffect<B, C, D, E, F, G, R>(
|
|
65
|
+
ab: ZeroFn<B>,
|
|
66
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
67
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
68
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
69
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
70
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
71
|
+
gh: AsyncOrSync<Awaited<G>, R>
|
|
72
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
73
|
+
function pipeAsyncSideEffect<B, C, D, E, F, G, H, R>(
|
|
74
|
+
ab: ZeroFn<B>,
|
|
75
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
76
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
77
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
78
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
79
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
80
|
+
gh: AsyncOrSync<Awaited<G>, H>,
|
|
81
|
+
hi: AsyncOrSync<Awaited<H>, R>
|
|
82
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
83
|
+
function pipeAsyncSideEffect<B, C, D, E, F, G, H, I, R>(
|
|
84
|
+
ab: ZeroFn<B>,
|
|
85
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
86
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
87
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
88
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
89
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
90
|
+
gh: AsyncOrSync<Awaited<G>, H>,
|
|
91
|
+
hi: AsyncOrSync<Awaited<H>, I>,
|
|
92
|
+
ij: AsyncOrSync<Awaited<I>, R>
|
|
93
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
94
|
+
function pipeAsyncSideEffect<B, C, D, E, F, G, H, I, J, R>(
|
|
95
|
+
ab: ZeroFn<B>,
|
|
96
|
+
bc: AsyncOrSync<Awaited<B>, C>,
|
|
97
|
+
cd: AsyncOrSync<Awaited<C>, D>,
|
|
98
|
+
de: AsyncOrSync<Awaited<D>, E>,
|
|
99
|
+
ef: AsyncOrSync<Awaited<E>, F>,
|
|
100
|
+
fg: AsyncOrSync<Awaited<F>, G>,
|
|
101
|
+
gh: AsyncOrSync<Awaited<G>, H>,
|
|
102
|
+
hi: AsyncOrSync<Awaited<H>, I>,
|
|
103
|
+
ij: AsyncOrSync<Awaited<I>, J>,
|
|
104
|
+
jk: AsyncOrSync<Awaited<J>, R>
|
|
105
|
+
): () => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
32
106
|
function pipeAsyncSideEffect<A, R>(
|
|
33
107
|
ab: AsyncOrSync<A, R>
|
|
34
108
|
): (a: A | SideEffect<any>) => Promise<MaybeSideEffect<Awaited<R>>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import compose from './compose';
|
|
3
|
+
import from from './from';
|
|
3
4
|
|
|
4
5
|
describe('compose', () => {
|
|
5
6
|
it('applies functions right-to-left', () => {
|
|
@@ -27,4 +28,17 @@ describe('compose', () => {
|
|
|
27
28
|
expect(fn(4)).toBe(16);
|
|
28
29
|
});
|
|
29
30
|
|
|
31
|
+
it('supports zero-arity tail functions', () => {
|
|
32
|
+
const addOne = (n: number) => n + 1;
|
|
33
|
+
const fn = compose(addOne, () => 2);
|
|
34
|
+
expect(fn()).toBe(3);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('supports from() as a constant source', () => {
|
|
38
|
+
const addOne = (n: number) => n + 1;
|
|
39
|
+
const fn = compose(addOne, from(2));
|
|
40
|
+
expect(fn()).toBe(3);
|
|
41
|
+
expect(fn(10)).toBe(3);
|
|
42
|
+
});
|
|
43
|
+
|
|
30
44
|
});
|
|
@@ -2,46 +2,158 @@
|
|
|
2
2
|
* compose - 함수를 우→좌로 합성
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { FromFn } from './from';
|
|
6
|
+
|
|
5
7
|
type UnaryFn<A, R> = (a: A) => R;
|
|
8
|
+
type ZeroFn<R> = () => R;
|
|
6
9
|
type ComposeInput<Fns extends UnaryFn<any, any>[]> = Fns extends [...UnaryFn<any, any>[], UnaryFn<infer A, any>]
|
|
7
10
|
? A
|
|
8
11
|
: never;
|
|
9
|
-
type
|
|
10
|
-
?
|
|
12
|
+
type ComposeOutput<Fns extends UnaryFn<any, any>[]> = Fns extends [UnaryFn<any, infer R>]
|
|
13
|
+
? R
|
|
11
14
|
: Fns extends [UnaryFn<infer A, infer R>, ...infer Rest]
|
|
12
|
-
? Rest extends [UnaryFn<
|
|
13
|
-
?
|
|
14
|
-
?
|
|
15
|
+
? Rest extends [UnaryFn<any, any>, ...UnaryFn<any, any>[]]
|
|
16
|
+
? ComposeOutput<Rest> extends A
|
|
17
|
+
? R
|
|
15
18
|
: never
|
|
16
19
|
: never
|
|
17
20
|
: never;
|
|
18
|
-
type Compose<Fns extends UnaryFn<any, any>[]> = (input: ComposeInput<Fns>) =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
>
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
type Compose<Fns extends UnaryFn<any, any>[]> = (input: ComposeInput<Fns>) => ComposeOutput<Fns>;
|
|
22
|
+
type ComposeFrom<Fns extends [...UnaryFn<any, any>[], FromFn<any>]> = (input?: ComposeInput<Fns>) => ComposeOutput<Fns>;
|
|
23
|
+
|
|
24
|
+
function compose<R>(ab: ZeroFn<R>): () => R;
|
|
25
|
+
function compose<B, R>(ab: UnaryFn<B, R>, bc: ZeroFn<B>): () => R;
|
|
26
|
+
function compose<C, B, R>(ab: UnaryFn<B, R>, bc: UnaryFn<C, B>, cd: ZeroFn<C>): () => R;
|
|
27
|
+
function compose<D, C, B, R>(ab: UnaryFn<B, R>, bc: UnaryFn<C, B>, cd: UnaryFn<D, C>, de: ZeroFn<D>): () => R;
|
|
28
|
+
function compose<E, D, C, B, R>(
|
|
29
|
+
ab: UnaryFn<B, R>,
|
|
30
|
+
bc: UnaryFn<C, B>,
|
|
31
|
+
cd: UnaryFn<D, C>,
|
|
32
|
+
de: UnaryFn<E, D>,
|
|
33
|
+
ef: ZeroFn<E>
|
|
34
|
+
): () => R;
|
|
35
|
+
function compose<F, E, D, C, B, R>(
|
|
36
|
+
ab: UnaryFn<B, R>,
|
|
37
|
+
bc: UnaryFn<C, B>,
|
|
38
|
+
cd: UnaryFn<D, C>,
|
|
39
|
+
de: UnaryFn<E, D>,
|
|
40
|
+
ef: UnaryFn<F, E>,
|
|
41
|
+
fg: ZeroFn<F>
|
|
42
|
+
): () => R;
|
|
43
|
+
function compose<G, F, E, D, C, B, R>(
|
|
44
|
+
ab: UnaryFn<B, R>,
|
|
45
|
+
bc: UnaryFn<C, B>,
|
|
46
|
+
cd: UnaryFn<D, C>,
|
|
47
|
+
de: UnaryFn<E, D>,
|
|
48
|
+
ef: UnaryFn<F, E>,
|
|
49
|
+
fg: UnaryFn<G, F>,
|
|
50
|
+
gh: ZeroFn<G>
|
|
51
|
+
): () => R;
|
|
52
|
+
function compose<H, G, F, E, D, C, B, R>(
|
|
53
|
+
ab: UnaryFn<B, R>,
|
|
54
|
+
bc: UnaryFn<C, B>,
|
|
55
|
+
cd: UnaryFn<D, C>,
|
|
56
|
+
de: UnaryFn<E, D>,
|
|
57
|
+
ef: UnaryFn<F, E>,
|
|
58
|
+
fg: UnaryFn<G, F>,
|
|
59
|
+
gh: UnaryFn<H, G>,
|
|
60
|
+
hi: ZeroFn<H>
|
|
61
|
+
): () => R;
|
|
62
|
+
function compose<I, H, G, F, E, D, C, B, R>(
|
|
63
|
+
ab: UnaryFn<B, R>,
|
|
64
|
+
bc: UnaryFn<C, B>,
|
|
65
|
+
cd: UnaryFn<D, C>,
|
|
66
|
+
de: UnaryFn<E, D>,
|
|
67
|
+
ef: UnaryFn<F, E>,
|
|
68
|
+
fg: UnaryFn<G, F>,
|
|
69
|
+
gh: UnaryFn<H, G>,
|
|
70
|
+
hi: UnaryFn<I, H>,
|
|
71
|
+
ij: ZeroFn<I>
|
|
72
|
+
): () => R;
|
|
73
|
+
function compose<J, I, H, G, F, E, D, C, B, R>(
|
|
74
|
+
ab: UnaryFn<B, R>,
|
|
75
|
+
bc: UnaryFn<C, B>,
|
|
76
|
+
cd: UnaryFn<D, C>,
|
|
77
|
+
de: UnaryFn<E, D>,
|
|
78
|
+
ef: UnaryFn<F, E>,
|
|
79
|
+
fg: UnaryFn<G, F>,
|
|
80
|
+
gh: UnaryFn<H, G>,
|
|
81
|
+
hi: UnaryFn<I, H>,
|
|
82
|
+
ij: UnaryFn<J, I>,
|
|
83
|
+
jk: ZeroFn<J>
|
|
84
|
+
): () => R;
|
|
24
85
|
|
|
86
|
+
function compose<Fns extends [...UnaryFn<any, any>[], FromFn<any>]>(...funcs: Fns): ComposeFrom<Fns>;
|
|
25
87
|
function compose<A, R>(ab: UnaryFn<A, R>): (a: A) => R;
|
|
26
|
-
function compose<A, B, R>(ab: UnaryFn<
|
|
27
|
-
function compose<A, B, C, R>(ab: UnaryFn<
|
|
88
|
+
function compose<A, B, R>(ab: UnaryFn<B, R>, bc: UnaryFn<A, B>): (a: A) => R;
|
|
89
|
+
function compose<A, B, C, R>(ab: UnaryFn<C, R>, bc: UnaryFn<B, C>, cd: UnaryFn<A, B>): (a: A) => R;
|
|
28
90
|
function compose<A, B, C, D, R>(
|
|
29
|
-
ab: UnaryFn<
|
|
30
|
-
bc: UnaryFn<
|
|
31
|
-
cd: UnaryFn<
|
|
32
|
-
de: UnaryFn<
|
|
91
|
+
ab: UnaryFn<D, R>,
|
|
92
|
+
bc: UnaryFn<C, D>,
|
|
93
|
+
cd: UnaryFn<B, C>,
|
|
94
|
+
de: UnaryFn<A, B>
|
|
33
95
|
): (a: A) => R;
|
|
34
96
|
function compose<A, B, C, D, E, R>(
|
|
35
|
-
ab: UnaryFn<
|
|
36
|
-
bc: UnaryFn<
|
|
97
|
+
ab: UnaryFn<E, R>,
|
|
98
|
+
bc: UnaryFn<D, E>,
|
|
37
99
|
cd: UnaryFn<C, D>,
|
|
100
|
+
de: UnaryFn<B, C>,
|
|
101
|
+
ef: UnaryFn<A, B>
|
|
102
|
+
): (a: A) => R;
|
|
103
|
+
function compose<A, B, C, D, E, F, R>(
|
|
104
|
+
ab: UnaryFn<F, R>,
|
|
105
|
+
bc: UnaryFn<E, F>,
|
|
106
|
+
cd: UnaryFn<D, E>,
|
|
107
|
+
de: UnaryFn<C, D>,
|
|
108
|
+
ef: UnaryFn<B, C>,
|
|
109
|
+
fg: UnaryFn<A, B>
|
|
110
|
+
): (a: A) => R;
|
|
111
|
+
function compose<A, B, C, D, E, F, G, R>(
|
|
112
|
+
ab: UnaryFn<G, R>,
|
|
113
|
+
bc: UnaryFn<F, G>,
|
|
114
|
+
cd: UnaryFn<E, F>,
|
|
38
115
|
de: UnaryFn<D, E>,
|
|
39
|
-
ef: UnaryFn<
|
|
116
|
+
ef: UnaryFn<C, D>,
|
|
117
|
+
fg: UnaryFn<B, C>,
|
|
118
|
+
gh: UnaryFn<A, B>
|
|
119
|
+
): (a: A) => R;
|
|
120
|
+
function compose<A, B, C, D, E, F, G, H, R>(
|
|
121
|
+
ab: UnaryFn<H, R>,
|
|
122
|
+
bc: UnaryFn<G, H>,
|
|
123
|
+
cd: UnaryFn<F, G>,
|
|
124
|
+
de: UnaryFn<E, F>,
|
|
125
|
+
ef: UnaryFn<D, E>,
|
|
126
|
+
fg: UnaryFn<C, D>,
|
|
127
|
+
gh: UnaryFn<B, C>,
|
|
128
|
+
hi: UnaryFn<A, B>
|
|
129
|
+
): (a: A) => R;
|
|
130
|
+
function compose<A, B, C, D, E, F, G, H, I, R>(
|
|
131
|
+
ab: UnaryFn<I, R>,
|
|
132
|
+
bc: UnaryFn<H, I>,
|
|
133
|
+
cd: UnaryFn<G, H>,
|
|
134
|
+
de: UnaryFn<F, G>,
|
|
135
|
+
ef: UnaryFn<E, F>,
|
|
136
|
+
fg: UnaryFn<D, E>,
|
|
137
|
+
gh: UnaryFn<C, D>,
|
|
138
|
+
hi: UnaryFn<B, C>,
|
|
139
|
+
ij: UnaryFn<A, B>
|
|
140
|
+
): (a: A) => R;
|
|
141
|
+
function compose<A, B, C, D, E, F, G, H, I, J, R>(
|
|
142
|
+
ab: UnaryFn<J, R>,
|
|
143
|
+
bc: UnaryFn<I, J>,
|
|
144
|
+
cd: UnaryFn<H, I>,
|
|
145
|
+
de: UnaryFn<G, H>,
|
|
146
|
+
ef: UnaryFn<F, G>,
|
|
147
|
+
fg: UnaryFn<E, F>,
|
|
148
|
+
gh: UnaryFn<D, E>,
|
|
149
|
+
hi: UnaryFn<C, D>,
|
|
150
|
+
ij: UnaryFn<B, C>,
|
|
151
|
+
jk: UnaryFn<A, B>
|
|
40
152
|
): (a: A) => R;
|
|
41
153
|
|
|
42
154
|
function compose<Fns extends [UnaryFn<any, any>, ...UnaryFn<any, any>[]]>(...funcs: Fns): Compose<Fns>;
|
|
43
155
|
function compose(...funcs: Array<UnaryFn<any, any>>): (input: any) => any;
|
|
44
|
-
function compose(...funcs: Array<(
|
|
156
|
+
function compose(...funcs: Array<(...args: any[]) => any>) {
|
|
45
157
|
return (value: any) => funcs.reduceRight((acc, fn) => fn(acc), value);
|
|
46
158
|
}
|
|
47
159
|
|