forked from xiyuyizhi/vod-fp.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.js
100 lines (90 loc) · 2.05 KB
/
core.js
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
import Logger from '../logger';
let logger = new Logger('base');
const curry = fn => {
const len = fn.length;
return function _curry(...args) {
if (args.length < len) {
return _curry.bind(null, ...args);
}
return fn.apply(null, args);
};
};
const compose2 = (x, y) => z => y(x(z));
const compose = (...fns) => {
const fnReversed = fns.reverse();
const filterd = fnReversed.filter(fn => typeof fn !== 'function');
if (filterd.length) {
logger.error(filterd.join(',') + ' not function ');
return;
}
if (fns.length === 2) {
return compose2(...fnReversed);
}
return args => {
return fnReversed.reduce((ret, fn) => fn(ret), args);
};
};
const map = curry((fn, mappable) => mappable.map(fn));
const forEach = curry((fn, list) => list.forEach(fn));
const filter = curry((fn, list) => list.filter(fn));
const reduce = curry((fn, init, arr) => arr.reduce(fn, init));
const split = curry((a, b) => b.split(a));
const splitOnce = curry((a, b) => {
let i = b.indexOf(a);
if (i === -1) {
return [b];
}
return [b.slice(0, i), b.slice(i + 1)];
});
const head = a => a[0];
const tail = a => a.slice(1);
const identity = a => a;
const splitMap = curry((fn1, fn2, list) => {
const [head, ...tail] = list;
return [fn1(head)].concat(map(fn2, tail));
});
const ifElse = curry((condition, fn1, fn2, arg) => {
if (condition(arg)) {
return fn1(arg);
}
return fn2(arg);
});
const prop = curry((a, b) => b[a]);
const join = curry(a => a.join());
const value = curry(a => a.value());
const chain = curry((f, m) => m.map(f).join());
const error = curry((f, m) => m.error(f));
const liftA2 = curry((g, a, b) => a.map(g).ap(b));
const trace = (msg, v) => {
if (typeof msg === 'string' && msg.indexOf('log:') !== -1) {
return v => {
logger.log(msg, v);
return v;
};
}
v = msg;
logger.log(v);
return v;
};
export {
curry,
compose,
map,
forEach,
filter,
reduce,
head,
tail,
identity,
split,
splitOnce,
splitMap,
join,
value,
chain,
error,
liftA2,
prop,
ifElse,
trace
};