Last active
June 11, 2018 16:17
-
-
Save tincho/4bf3eae5ec237e925b26c04cef9077f1 to your computer and use it in GitHub Desktop.
all functional-programming js tools i've written
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
// var logHello = _partial(console.log, "hello "); | |
// logHello("world"); | |
// accepts _partial (fn reference) as placeholder just like underscore accepts _ | |
// var partialApplied = _partial(originalFn, _partial, "second", _partial, "fifth"); | |
// partialApplied("first", "third") will call originalFn("first", "second", "third", "fifth") | |
function _partial() { | |
var args = Array.prototype.slice.call(arguments); | |
var method = args.shift(); | |
var self = this; | |
var placeHolderPos = []; | |
args.forEach(function(arg, i) { | |
arg === self && placeHolderPos.push(i); | |
}); | |
// remove placeholders! | |
args = args.filter(_notEqual.bind(undefined, self)); | |
return function() { | |
var thisArguments = Array.prototype.slice.call(arguments); | |
placeHolderPos.forEach(function(pos) { | |
var arg = thisArguments.shift(); | |
args.splice(pos, 0, arg); | |
}); | |
var applyArguments = args.concat(thisArguments); | |
return method.apply(undefined, applyArguments); | |
} | |
} | |
}; | |
// n-ary a function to accept only N (arity) of the arguments passed | |
// suppouse: | |
// getManyThings.then(function(a, b, c) { // i Just want to do console.log(a) }); | |
// if I do: getManyThings.then(console.log);, console.log will receive a, b and C. | |
// how do I prevent it? | |
// With arity: (https://en.wikipedia.org/wiki/Arity) | |
// getManyThings.then(_ary(console.log)); | |
function _ary(fn, arity) { | |
// default arity is 1 | |
arity = arity || 1; | |
return function() { | |
var args = Array.prototype.slice.call(arguments, 0, arity); | |
return fn.apply(null, args); | |
}; | |
} | |
// _compose(sum1, divide2, multiply5)(5) === 15 | |
function _compose() { | |
var fs = Array.prototype.slice.call(arguments); | |
return function(x) { | |
return fs.reduce(function(p, f) { return f(p); }, x); | |
} | |
} | |
function _noop() {} | |
function _constant(v) { return function() { return v; }; } | |
function _notEqual(a, b) { return a !== b; } | |
// returns true if *any* of the arguments evaluates true | |
function _or() { | |
var args = Array.prototype.slice.call(arguments); | |
args = Array.prototype.concat.apply([], args); | |
var token = 0; | |
for (var i = 0; i < args.length; i++) { | |
token += +!!args[i]; | |
} | |
return !!token; | |
} | |
// this should be a little more performant than doing something like: | |
// [some(), other(), another()].some(v => !!v); | |
// returns true if *all* of the arguments evaluates true | |
function _and() { | |
var token = 1; | |
var args = Array.prototype.slice.call(arguments); | |
args = Array.prototype.concat.apply([], args); | |
for (var i = 0; i < args.length; i++) { | |
token *= +!!args[i]; | |
} | |
return !!token; | |
} | |
// _if(condition, thenFunction[, elseFunction]); | |
function _if() { | |
// ES6: | |
// var args = ...arguments; | |
var args = Array.prototype.slice.call(arguments); | |
var cond = args.shift(); | |
if (typeof cond === "function") { cond = cond(); } | |
var noop = function(){}; | |
return (args[+!cond] || noop).apply(this); | |
} | |
// "functional _if = _fif" | |
function _fif() { | |
// ES6: | |
// return _if.bind(this, ...arguments); | |
var args = Array.prototype.slice.call(arguments); | |
return function() { return _if.apply(this, args); } | |
} | |
// domElementsArray.forEach( _method("addEventListener", "click", clickHandler) ); | |
function _method(method) { | |
var callArgs = [].slice.call(arguments, 1); | |
return function(obj) { | |
return obj[method].apply(obj, callArgs); | |
} | |
} | |
test code (try it on http://tddbin.com)
function compose() {
var fs = Array.prototype.slice.call(arguments);
return function(x) {
return fs.reduce(function(p, f) {
return f(p);
}, x);
}
}
function getProperty(prop) {
return function(obj) {
return obj[prop];
}
}
function _if() {
// ES6:
// var args = ...arguments;
var args = Array.prototype.slice.call(arguments);
var cond = args.shift();
if (typeof cond === "function") { cond = cond(); }
var noop = function(){};
return (args[+!cond] || noop).apply(this);
}
function _fif() {
// ES6:
// return _if.bind(this, ...arguments);
var args = Array.prototype.slice.call(arguments);
return function(cond) {
// ES6:
// args = [cond, ...args];
args.splice(0,0, cond);
return _if.apply(this, args);
}
}
function valueForViewA() { return "A" }
function valueForViewB() { return "B" }
describe("if", () => {
it("test 1", () => {
const getFromServer = () => ({Enabled: true});
const value = compose(
getFromServer,
getProperty("Enabled"),
_fif(valueForViewA, valueForViewB)
)();
console.log(value);
assert( value === "A" );
});
it("test 2", () => {
const getFromServer = () => ({Enabled: false});
const value = compose(
getFromServer,
getProperty("Enabled"),
_fif( valueForViewA, valueForViewB)
)();
console.log(value);
assert( value === "B" );
});
})
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
_if
use cases: