-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathfunction.js
More file actions
112 lines (93 loc) · 2.67 KB
/
function.js
File metadata and controls
112 lines (93 loc) · 2.67 KB
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
function memoize(f) {
const wm = new WeakMap();
return function(obj, ...rest) {
if (typeof obj != 'object') return f(obj, ...rest);
if (wm.has(obj)) return wm.get(obj);
const val = f(obj, ...rest);
wm.set(obj, val);
return val;
};
}
function clone(data) {
if (data == null || typeof data != 'object') return data;
return Array.isArray(data) ? [...data] : Object.assign({}, data);
}
function reduce(f, data) {
return arguments.length == 1 ?
reduceAcc(f, undefined) : baseReduce(f, undefined, data);
}
function reduceAcc(f, acc, data) {
// Currying
if (arguments.length == 1) return (...args) => reduceAcc(f, ...args);
if (arguments.length == 2) return data => reduceAcc(f, clone(acc), data);
return baseReduce(f, acc, data);
}
function baseReduce(f, acc, data) {
if (data == null) return;
let isNotArrayLike = typeof data.length != 'number';
if (isNotArrayLike && data[Symbol.iterator]) return baseReduceIter(f, acc, data);
var i = -1, l = (data = isNotArrayLike ? Object.values(data) : data).length;
return callP(function recur(acc) {
while (++i < l)
if ((acc = f(acc, data[i])) instanceof Promise)
return acc.then(recur);
return acc;
}, acc === undefined ? data[++i] : acc);
}
function baseReduceIter(f, acc, data) {
let iter = toIterator(data);
return callP(function recur(acc) {
for (const val of iter)
if ((acc = f(acc, val)) instanceof Promise)
return acc.then(recur);
return acc;
}, acc === undefined ? iter.next().value : acc);
}
function toIterator(data) {
return typeof data.values == 'function' ? data.values() : data[Symbol.iterator]();
}
function callP(f, p) {
return p instanceof Promise ? p.then(f) : f(p);
}
class Tuple {
constructor() {
this.value = arguments;
}
[Symbol.iterator]() {
return this.value[Symbol.iterator]();
}
}
function tuple(...args) {
var l = args.length;
while (l--) if (args[l] instanceof Promise) return Promise.all(args).then(toTuple);
return new Tuple(...args);
}
function toTuple(list) {
return list.length == 1 && list[0] instanceof Tuple ? list[0] : new Tuple(...list);
}
function isTuple(tp) {
return tp instanceof Tuple;
}
function call(f, arg) {
return f(arg);
}
function callRight(arg, f) {
return f(arg);
}
function callTp(f, arg) {
return callTpRight(arg, f);
}
function callTpRight(arg, f) {
return arg instanceof Tuple ? f(...arg) : f(arg);
}
function go(arg, f) {
return Array.isArray(f) ?
reduceAcc(callTpRight, arg, f) :
reduce(callTpRight, arguments);
}
function pipe(f) {
var fs = Array.isArray(f) ? f : arguments;
return function() {
return reduceAcc(callTpRight, toTuple(arguments), fs);
}
}