Created
January 21, 2019 00:51
-
-
Save brianneisler/c747c9056754aedc4f59c5d53b2ed2bb to your computer and use it in GitHub Desktop.
functionCurryN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const functionCurry1 = (func) => { | |
return function f1(arg0, ...rest) { | |
if (arguments.length === 0) { | |
throw new Error('curried method called with no arguments') | |
} | |
if (anyIsPlaceholder(arg0)) { | |
if (rest.length > 0) { | |
throw new Error('use of a placeholder with additional arguments is not supported') | |
} | |
return f1 | |
} | |
// functionValidateArg(arg0, 0, func) | |
return func.apply(this, arguments) | |
} | |
} | |
const functionCurry2 = (fn) => { | |
return function f2(a, b) { | |
switch (arguments.length) { | |
case 0: | |
throw new Error('curried method called with no arguments') | |
case 1: | |
return anyIsPlaceholder(a) | |
? f2 | |
: functionCurry1(function(_b) { | |
return fn(a, _b) | |
}) | |
default: | |
return anyIsPlaceholder(a) && anyIsPlaceholder(b) | |
? f2 | |
: anyIsPlaceholder(a) | |
? functionCurry1(function(_a) { | |
return fn(_a, b) | |
}) | |
: anyIsPlaceholder(b) | |
? functionCurry1(function(_b) { | |
return fn(a, _b) | |
}) | |
: fn(a, b) | |
} | |
} | |
} | |
const functionCurry3 = (fn) => { | |
return function f3(a, b, c) { | |
switch (arguments.length) { | |
case 0: | |
throw new Error('curried method called with no arguments') | |
case 1: | |
return anyIsPlaceholder(a) | |
? f3 | |
: functionCurry2(function(_b, _c) { | |
return fn(a, _b, _c) | |
}) | |
case 2: | |
return anyIsPlaceholder(a) && anyIsPlaceholder(b) | |
? f3 | |
: anyIsPlaceholder(a) | |
? functionCurry2(function(_a, _c) { | |
return fn(_a, b, _c) | |
}) | |
: anyIsPlaceholder(b) | |
? functionCurry2(function(_b, _c) { | |
return fn(a, _b, _c) | |
}) | |
: functionCurry1(function(_c) { | |
return fn(a, b, _c) | |
}) | |
default: | |
return anyIsPlaceholder(a) && anyIsPlaceholder(b) && anyIsPlaceholder(c) | |
? f3 | |
: anyIsPlaceholder(a) && anyIsPlaceholder(b) | |
? functionCurry2(function(_a, _b) { | |
return fn(_a, _b, c) | |
}) | |
: anyIsPlaceholder(a) && anyIsPlaceholder(c) | |
? functionCurry2(function(_a, _c) { | |
return fn(_a, b, _c) | |
}) | |
: anyIsPlaceholder(b) && anyIsPlaceholder(c) | |
? functionCurry2(function(_b, _c) { | |
return fn(a, _b, _c) | |
}) | |
: anyIsPlaceholder(a) | |
? functionCurry1(function(_a) { | |
return fn(_a, b, c) | |
}) | |
: anyIsPlaceholder(b) | |
? functionCurry1(function(_b) { | |
return fn(a, _b, c) | |
}) | |
: anyIsPlaceholder(c) | |
? functionCurry1(function(_c) { | |
return fn(a, b, _c) | |
}) | |
: fn(a, b, c) | |
} | |
} | |
} | |
const functionCurryN = (fn, length, received = []) => { | |
if (length <= 0) { | |
throw new TypeError('functionCurryN method expects length to be greater than 0') | |
} | |
if (received.length === 0) { | |
switch (length) { | |
case 1: | |
return functionCurry1(fn) | |
case 2: | |
return functionCurry2(fn) | |
case 3: | |
return functionCurry3(fn) | |
} | |
} | |
return function() { | |
const combined = [] | |
let argsIdx = 0 | |
let left = length | |
let combinedIdx = 0 | |
while (combinedIdx < received.length || argsIdx < arguments.length) { | |
let result | |
if ( | |
combinedIdx < received.length && | |
(!anyIsPlaceholder(received[combinedIdx]) || argsIdx >= arguments.length) | |
) { | |
result = received[combinedIdx] | |
} else { | |
result = arguments[argsIdx] | |
argsIdx += 1 | |
} | |
combined[combinedIdx] = result | |
if (!anyIsPlaceholder(result)) { | |
left -= 1 | |
} | |
combinedIdx += 1 | |
} | |
return left <= 0 | |
? fn.apply(this, combined) | |
: functionArity(functionCurryN(fn, length, combined), left) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment