-
Notifications
You must be signed in to change notification settings - Fork 7
/
ap.ts
57 lines (49 loc) · 1.62 KB
/
ap.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Copyright (c) 2020 Jozty. All rights reserved. MIT license.
import curryN from './utils/curry_n.ts';
import type { Curry2, Func, FuncArr1 } from './utils/types.ts';
import { concat } from './concat.ts';
import { reduce } from './reduce.ts';
import { map } from './map.ts';
import { isFunction } from './utils/is.ts';
type ApplyFAp<T = unknown, R = unknown> = {
ap: FuncArr1<T[] | Func | T, R>;
};
type ApplyF<T = unknown, R = unknown> =
| FuncArr1<T, R>
| FuncArr1<T, R>[]
| ApplyFAp<T, R>;
function _checkForCustomAp<T, R>(
applyF: ApplyF<T, R>,
): applyF is ApplyFAp<T, R> {
return isFunction((applyF as ApplyFAp<T, R>).ap);
}
function _ap<T, R>(applyF: ApplyF<T, R>, applyX: T[] | Func) {
if (_checkForCustomAp(applyF)) {
return applyF.ap(applyX);
}
if (isFunction(applyF) && isFunction(applyX)) {
// deno-lint-ignore no-explicit-any
return (x: T) => (applyF(x) as any)(applyX(x));
}
return reduce(
(acc: T[], f: Func) => concat(acc, map(f, applyX) as T[]),
[],
// @ts-ignore: fix later
applyF,
);
}
/**
* Iit applies a list of functions to a list of values.
* Dispatches to the `ap` method of the second argument, if present. Also
* treats curried functions as applicatives.
*
* const mul2 = Fae.multiply(2)
* const add3 = Fae.add(3)
* Fae.ap([mul2, add3], [1, 2, 3]) // [2, 4, 6, 4, 5, 6])
* const h = Fae.ap(f, mul2)
* h(10) // 10 + (10 * 2))
* const obj = {ap: (n: number) => 'called ap with ' + n}
* Fae.ap(obj, 10) // 'called ap with 10'
*/
// deno-lint-ignore no-explicit-any
export const ap = curryN(2, _ap) as Curry2<ApplyF, any, any>;