moy-fp
Version:
A functional programming library.
103 lines (92 loc) • 2.4 kB
JavaScript
import __ from './__'
const _arity = (n, fn) => {
/* eslint-disable no-unused-vars */
switch(n){
case 0:
return function(){
return fn.apply(null, arguments);
};
case 1:
return function(a0){
return fn.apply(null, arguments);
};
case 2:
return function(a0, a1){
return fn.apply(null, arguments);
};
case 3:
return function(a0, a1, a2){
return fn.apply(null, arguments);
};
case 4:
return function(a0, a1, a2, a3){
return fn.apply(null, arguments);
};
case 5:
return function(a0, a1, a2, a3, a4){
return fn.apply(null, arguments);
};
case 6:
return function(a0, a1, a2, a3, a4, a5){
return fn.apply(null, arguments);
};
case 7:
return function(a0, a1, a2, a3, a4, a5, a6){
return fn.apply(null, arguments);
};
case 8:
return function(a0, a1, a2, a3, a4, a5, a6, a7){
return fn.apply(null, arguments);
};
case 9:
return function(a0, a1, a2, a3, a4, a5, a6, a7, a8){
return fn.apply(null, arguments);
};
case 10:
return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9){
return fn.apply(null, arguments);
};
default:
return function(...args){
return fn.apply(null, arguments)
}
}
}
const _curry = (length, received, fn) => (...args) => {
const combined = [],
receivedLength = received.length,
argsLength = args.length
let left = length,
receivedIndex = 0,
argsIndex = 0,
has__ = false,
combinedOne
while(receivedIndex < receivedLength ||
argsIndex < argsLength){
if(receivedIndex < receivedLength &&
(received[receivedIndex] !== __ || argsIndex >= argsLength)
){
combinedOne = received[receivedIndex]
}else{
combinedOne = args[argsIndex ++]
}
if(combinedOne !== __){
left --
}else{
if(combined.length <= length){
has__ = true
}
}
combined.push(combinedOne)
receivedIndex ++
}
return left <= 0 && !has__ ? fn.apply(null, combined) : _arity(left, _curry(length, combined, fn))
}
/**
* ((a, b, c, ..., m) -> n) -> ((a, b, c, ..., m) -> n)
*/
const curry = fn => {
const length = fn.length
return _arity(length, _curry(length, [], fn))
}
export default curry