pepka 0.12.2 → 0.13.0-b1

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/src/curry.ts CHANGED
@@ -1,53 +1,99 @@
1
-
2
- type Args = any[]
3
-
4
- export const __ = (function Placeholder() {})
5
-
6
- const countArgs = (s: Args) => {
7
- let i = 0
8
- for (const v of s) v!==__ && i++
9
- return i
10
- }
11
-
12
- // TODO: try to make it mutable.
13
- // { 0: __, 1: 10 }, [ 11 ]
14
- const addArgs = (args: Args, _args: Args) => {
15
- const len = args.length
16
- const new_args = args.slice()
17
- const _args_len = _args.length
18
- let _args_left = _args_len
19
- let i=0
20
- for (; _args_left && i<len; i++) {
21
- if(new_args[i] === __) {
22
- new_args[i] = _args[_args_len-_args_left]
23
- _args_left--
24
- }
25
- }
26
- for(i=len; _args_left; i++, _args_left--) {
27
- new_args[i] = _args[_args_len-_args_left]
28
- }
29
- return new_args
30
- }
31
-
32
- const _curry = (fn: Function, args: Args, new_args: Args) => {
33
- const args2add = fn.length - args.length - countArgs(new_args)
34
- if(args2add < 1) {
35
- return fn(...addArgs(args, new_args))
36
- } else {
37
- const curried = (...__args: Args) => _curry(
38
- fn,
39
- addArgs(args, new_args),
40
- __args
41
- )
42
- ;(curried as any).$args_left = args2add
43
- return curried
44
- }
45
- }
46
-
47
- export const curry = (
48
- (fn: Function) => (
49
- (...args: Args) => fn.length>countArgs(args)
50
- ? _curry(fn, [], args)
51
- : fn(...args)
52
- )
53
- )
1
+ import { F as FT, A } from 'ts-toolbelt'
2
+ import { AnyFunc, AnyArgs } from "./types"
3
+
4
+ export const __ = Symbol('Placeholder') as A.x
5
+
6
+ const countArgs = (s: AnyArgs) => {
7
+ let i = 0
8
+ for (const v of s) v!==__ && i++
9
+ return i
10
+ }
11
+
12
+ // TODO: try to make it mutable.
13
+ // { 0: __, 1: 10 }, [ 11 ]
14
+ const addArgs = (args: AnyArgs, _args: AnyArgs) => {
15
+ const len = args.length
16
+ const new_args = args.slice()
17
+ const _args_len = _args.length
18
+ let _args_left = _args_len
19
+ let i=0
20
+ for (; _args_left && i<len; i++) {
21
+ if(new_args[i] === __) {
22
+ new_args[i] = _args[_args_len-_args_left]
23
+ _args_left--
24
+ }
25
+ }
26
+ for(i=len; _args_left; i++, _args_left--) {
27
+ new_args[i] = _args[_args_len-_args_left]
28
+ }
29
+ return new_args
30
+ }
31
+
32
+ const _curry = (fn: Function, args: AnyArgs, new_args: AnyArgs) => {
33
+ const args2add = fn.length - args.length - countArgs(new_args)
34
+ if(args2add < 1) {
35
+ return fn(...addArgs(args, new_args))
36
+ } else {
37
+ const curried = (...__args: AnyArgs) => _curry(
38
+ fn,
39
+ addArgs(args, new_args),
40
+ __args
41
+ )
42
+ ;(curried as any).$args_left = args2add
43
+ return curried
44
+ }
45
+ }
46
+
47
+ export const curry = (
48
+ <Func extends AnyFunc>(fn: AnyFunc) => (
49
+ (...args: AnyArgs) => fn.length>countArgs(args)
50
+ ? _curry(fn, [], args)
51
+ : fn(...args)
52
+ ) as FT.Curry<Func>
53
+ )
54
+ // type EndlessPh<Func extends FT.Function, ArgT> =
55
+ // (a: ArgT) => ReturnType<Func>
56
+ // | ((a: A.x) => EndlessPh<Func, ArgT>)
57
+ const endlessph = <Func extends FT.Function>(fn: Func) => {
58
+ type ReturnT = ReturnType<Func>
59
+ type p0 = Parameters<Func>[0]
60
+ function _endlessph(a: p0): ReturnT
61
+ function _endlessph(a: A.x): Func
62
+ function _endlessph(a: p0 | A.x) {
63
+ return a===__ ? fn : fn(a)
64
+ }
65
+ return _endlessph
66
+ }
67
+
68
+ type Func2 = (a: any, b: any) => any
69
+ export function curry2<Func extends Func2>(fn: Func) {
70
+ type p0 = Parameters<Func>[0]
71
+ type p1 = Parameters<Func>[1]
72
+ type ReturnT = ReturnType<Func>
73
+ function curried2( a: p0 ): (b: p1) => ReturnT
74
+ function curried2( a: p0, b: p1 ): ReturnT
75
+ function curried2( a: A.x, b: p1 ): (a: p0) => ReturnT
76
+ function curried2( a: p0, b: A.x ): (b: p1) => ReturnT
77
+ function curried2( a: p0 | A.x, b?: p1 ) {
78
+ const withPlaceholder1 = a===__
79
+ const aln = arguments.length
80
+ if(aln === 1 && withPlaceholder1)
81
+ throw new Error('Senseless placeholder usage.')
82
+ return arguments.length>1
83
+ ? withPlaceholder1
84
+ ? endlessph((a: p0) => fn(a, b))
85
+ : fn(a, b) as ReturnType<Func>
86
+ : (b: p1) => fn(a, b)
87
+ }
88
+ return curried2
89
+ }
90
+
91
+ type Func3 = (a: any, b: any, c: any) => any
92
+ export function curry3<Func extends Func3>(fn: Func) {
93
+ // type p0 = Parameters<Func>[0]
94
+ // type p1 = Parameters<Func>[1]
95
+ // type p2 = Parameters<Func>[2]
96
+ // type ReturnT = ReturnType<Func>
97
+ // TODO: optimize.
98
+ return curry(fn)
99
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
-
2
- export * from './curry'
3
- export * from './common'
4
- export * from './safe'
5
- export * from './quick'
1
+
2
+ export * from './curry'
3
+ export * from './uncurry'
4
+ export * from './common'
5
+ export * from './safe'
6
+ export * from './quick'
6
7
  export * from './strings'
package/src/quick.ts CHANGED
@@ -1,98 +1,99 @@
1
- import { curry } from "./curry"
2
- import { type } from "./common"
3
- import { AnyObject, Reducer, AnyFunc } from "./types"
4
- import { isFunc, isArray } from "./utils"
5
-
6
- export const qappend = curry((s: any, xs: any[]) => {xs.push(s); return xs})
7
- export const qassoc = curry(
8
- (prop: string, v: any, obj: AnyObject) => {
9
- obj[prop] = v
10
- return obj
11
- }
12
- )
13
- export const qreduce = curry(
14
- (fn: Reducer, accum: any, arr: any[]) =>
15
- arr.reduce(fn, accum)
16
- )
17
- // strategy is for arrays: 1->clean, 2->merge, 3->push.
18
- const mergeDeep = curry((strategy: 1|2|3, o1: AnyObject, o2: AnyObject): AnyObject => {
19
- for(let k in o2) {
20
- switch(type(o2[k])) {
21
- case 'Array':
22
- if(strategy>1 && type(o1[k])==='Array') {
23
- switch(strategy) {
24
- case 2:
25
- const o1k = o1[k], o2k = o2[k]
26
- for(const i in o2k) {
27
- if(o1k[i]) {
28
- mergeDeep(strategy, o1k[i], o2k[i])
29
- } else {
30
- o1k[i] = o2k[i]
31
- }
32
- }
33
- break
34
- case 3: o1[k].push(...o2[k])
35
- default: break
36
- }
37
- } else {
38
- o1[k] = o2[k]
39
- }
40
- break
41
- case 'Object':
42
- if(type(o1[k])==='Object') {
43
- mergeDeep(strategy, o1[k], o2[k])
44
- break
45
- }
46
- default:
47
- o1[k] = o2[k]
48
- break
49
- }
50
- }
51
- return o1
52
- })
53
- export const qmergeDeep = mergeDeep(1)
54
- export const qmergeDeepX = mergeDeep(2)
55
- export const qmergeDeepAdd = mergeDeep(3)
56
- /** qmapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
57
- export const qmapKeys = curry(
58
- (
59
- keyMap: {[oldKey: string]: string},
60
- o: AnyObject
61
- ) => {
62
- let k: string, mapped: string | AnyFunc, newKey: string, newValue: any
63
- for(k in keyMap) {
64
- mapped = keyMap[k]
65
- ;[newKey, newValue] = isFunc(mapped)
66
- ? (mapped as unknown as AnyFunc)(o)
67
- : [mapped, o[k]]
68
- o[newKey] = newValue
69
- if(k !== newKey) {
70
- delete o[k]
71
- }
72
- }
73
- return o
74
- }
75
- )
76
-
77
- export const qfilter = curry(
78
- (
79
- cond: (v: any, k: string | number) => boolean,
80
- data: any[] | AnyObject
81
- ) => {
82
- const isArr = isArray(data)
83
- for(let k in data) {
84
- if(!cond(data[k], k)) {
85
- if(isArr) {
86
- data.splice(k, 1)
87
- } else {
88
- // TODO: handle Maps and Sets ?
89
- delete data[k]
90
- }
91
- }
92
- }
93
- return data
94
- }
95
- )
96
- export const qindexOf = curry(
97
- (x: any, xs: any[]) => xs.indexOf(x)
1
+ import { curry, curry2, curry3 } from "./curry"
2
+ import { type } from "./common"
3
+ import { AnyObject, Reducer, AnyFunc } from "./types"
4
+ import { isFunc, isArray } from "./utils"
5
+
6
+ export const qappend = curry2((s: any, xs: any[]) => {xs.push(s); return xs})
7
+ export const qassoc = curry3(
8
+ (prop: string, v: any, obj: AnyObject) => {
9
+ obj[prop] = v
10
+ return obj
11
+ }
12
+ )
13
+ export const qreduce = curry3(
14
+ (fn: Reducer, accum: any, arr: any[]) =>
15
+ arr.reduce(fn, accum)
16
+ )
17
+ // strategy is for arrays: 1->clean, 2->merge, 3->push.
18
+ const mergeDeep = curry3((strategy: 1|2|3, o1: AnyObject, o2: AnyObject): AnyObject => {
19
+ for(let k in o2) {
20
+ switch(type(o2[k])) {
21
+ case 'Array':
22
+ if(strategy>1 && type(o1[k])==='Array') {
23
+ switch(strategy) {
24
+ case 2:
25
+ const o1k = o1[k], o2k = o2[k]
26
+ for(const i in o2k) {
27
+ if(o1k[i]) {
28
+ mergeDeep(strategy, o1k[i], o2k[i])
29
+ } else {
30
+ o1k[i] = o2k[i]
31
+ }
32
+ }
33
+ break
34
+ case 3: o1[k].push(...o2[k])
35
+ default: break
36
+ }
37
+ } else {
38
+ o1[k] = o2[k]
39
+ }
40
+ break
41
+ case 'Object':
42
+ if(type(o1[k])==='Object') {
43
+ mergeDeep(strategy, o1[k], o2[k])
44
+ break
45
+ }
46
+ default:
47
+ o1[k] = o2[k]
48
+ break
49
+ }
50
+ }
51
+ return o1
52
+ })
53
+ export const qmergeDeep = mergeDeep(1)
54
+ export const qmergeDeepX = mergeDeep(2)
55
+ export const qmergeDeepAdd = mergeDeep(3)
56
+ /** qmapKeys({ a: 'b' }, { a: 44 }) -> { b: 44 } */
57
+ export const qmapKeys = curry2(
58
+ (
59
+ keyMap: {[oldKey: string]: string},
60
+ o: AnyObject
61
+ ) => {
62
+ let k: string, mapped: string | AnyFunc, newKey: string, newValue: any
63
+ for(k in keyMap) {
64
+ mapped = keyMap[k]
65
+ ;[newKey, newValue] = isFunc(mapped)
66
+ ? (mapped as unknown as AnyFunc)(o)
67
+ : [mapped, o[k]]
68
+ o[newKey] = newValue
69
+ if(k !== newKey) {
70
+ delete o[k]
71
+ }
72
+ }
73
+ return o
74
+ }
75
+ )
76
+
77
+ export const qfilter = curry2(
78
+ (
79
+ cond: (v: any, k: string | number) => boolean,
80
+ data: any[] | AnyObject
81
+ ) => {
82
+ const isArr = isArray(data)
83
+ for(let k in data) {
84
+ if(!cond(data[k], k)) {
85
+ if(isArr) {
86
+ data.splice(k, 1)
87
+ } else {
88
+ // TODO: handle Maps and Sets ?
89
+ delete data[k]
90
+ }
91
+ }
92
+ }
93
+ return data
94
+ }
95
+ )
96
+ /** @deprecated */
97
+ export const qindexOf = curry2(
98
+ (x: any, xs: any[]) => xs.indexOf(x)
98
99
  )