-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathcurryArity.js
93 lines (87 loc) · 2.12 KB
/
curryArity.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
const __ = require('./placeholder')
/**
* @name _curryArity
*
* @synopsis
* ```coffeescript [specscript]
* __ = Symbol(placeholder)
*
* var arity number,
* func function,
* args Array<__|any>,
* curried function
*
* _curryArity(arity, func, args) -> curried|any
* ```
*/
const _curryArity = (arity, func, args) => function curried(...curriedArgs) {
const argsLength = args.length,
curriedArgsLength = curriedArgs.length,
nextArgs = []
let argsIndex = -1,
curriedArgsIndex = -1,
numCurriedPlaceholders = 0
while (++argsIndex < argsLength) {
const arg = args[argsIndex]
if (arg == __ && (curriedArgsIndex += 1) < curriedArgsLength) {
const curriedArg = curriedArgs[curriedArgsIndex]
if (curriedArg == __) {
numCurriedPlaceholders += 1
}
nextArgs.push(curriedArg)
} else {
nextArgs.push(arg)
}
if (nextArgs.length == arity) {
return numCurriedPlaceholders == 0
? func(...nextArgs)
: curryArity(arity, func, nextArgs)
}
}
while (++curriedArgsIndex < curriedArgsLength) {
const curriedArg = curriedArgs[curriedArgsIndex]
if (curriedArg == __) {
numCurriedPlaceholders += 1
}
nextArgs.push(curriedArg)
if (nextArgs.length == arity) {
return numCurriedPlaceholders == 0
? func(...nextArgs)
: curryArity(arity, func, nextArgs)
}
}
return curryArity(arity, func, nextArgs)
}
/**
* @name curryArity
*
* @synopsis
* ```coffeescript [specscript]
* __ = Symbol(placeholder)
*
* var arity number,
* func function,
* args Array<__|any>,
* curried function
*
* curryArity(arity, func, args) -> curried|any
* ```
*
* @description
* Create a curried version of a function with specified arity.
*/
const curryArity = function (arity, func, args) {
const argsLength = args.length
if (argsLength < arity) {
return _curryArity(arity, func, args)
}
let argsIndex = -1
while (++argsIndex < argsLength) {
const arg = args[argsIndex]
if (arg == __) {
return _curryArity(arity, func, args)
}
}
return func(...args)
}
module.exports = curryArity