Skip to content

Instantly share code, notes, and snippets.

@torgeir
Last active May 18, 2017 07:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torgeir/f1c09aaee60e302cdbd9 to your computer and use it in GitHub Desktop.
Save torgeir/f1c09aaee60e302cdbd9 to your computer and use it in GitHub Desktop.
Playing with js combinators.
var log = console.log.bind(console);
var arr = [1, 2, undefined, 3];
var unary = (v) => v;
var binary = (first, rest) => [first, rest];
log('unary', unary.apply(null, arr)); // 1
log('binary', binary.apply(null, arr)); // [1, 2]
var variadic = fn => {
var numArgs = fn.length;
return function () {
var args = [].slice.call(arguments);
var firstArgs = args.slice(0, numArgs - 1);
var restArgs = args.slice(numArgs - 1, args.length);
var newArgs = firstArgs.concat([restArgs]);
return fn.apply(this, newArgs);
};
};
var oneRest = variadic((one, rest) => log('oneRest', one, rest));
var twoRest = variadic((one, two, rest) => log('twoRest', one, two, rest));
oneRest.apply(null, arr); // 1 [ 2, undefined, 3 ]
twoRest.apply(null, arr); // 1 2 [ undefined, 3 ]
log('variadic unary', variadic(unary).apply(null, arr)); // [ 1, 2, undefined, 3 ]
log('variadic binary', variadic(binary).apply(null, arr)); // [ 1, [ 2, undefined, 3 ] ]
var map = (args, fn) => args.map(fn);
var filter = (args, predicate) => {
var res = [];
map(args, arg => predicate(arg) ? res.push(arg) : undefined);
return res;
};
log('map * 2', map(arr, n => n * 2)); // [ 2, 4, NaN, 6 ]
log('filter > 2', filter(arr, n => n > 2)); // [ 3 ]
var flip = fn => (a, b) => {
var isCalledWithBothArgs = (typeof b !== 'undefined');
if (isCalledWithBothArgs)
return fn.call(this, b, a);
return b => fn.call(this, b, a);
};
var getWith = attr => obj => obj[attr];
var mapWith = flip(map);
var filterWith = flip(filter);
var pluckWith = arg => mapWith(getWith(arg));
var names = [{ name: 'alice' }, { name: 'bob' }];
log('pluckWith name', pluckWith('name')(names)); // [ 'alice', 'bob' ]
var isValue = val => (val !== null && val !== undefined);
var maybe = fn => arg =>
isValue(arg)
? fn(arg)
: undefined;
var add = m => mapWith(maybe(n => n + m));
var times = m => mapWith(maybe(n => n * m));
log('safe + 4', add(2)(arr)); // [ 3, 4, undefined, 5 ]
log('safe * 4', times(4)(arr)); // [ 4, 8, undefined, 12 ]
var filterLargerThan = m =>
filterWith(maybe(n => n > m));
var prepender = prefix =>
mapWith(maybe(arg => prefix + arg));
var compose = (fn, fnn) => arg => fn(fnn(arg));
var pipeline = flip(compose);
var values = [
{ value: -2 },
{ value: undefined },
{ value: -1 },
{ value: 0 },
{ value: 1 },
{ value: 2 } ];
var transformInterrestingNumbers = pipeline(
pluckWith('value'), pipeline(
filterWith(isValue), pipeline(
add(100), pipeline(
times(2), pipeline(
filterLargerThan(200),
prepender('#'))))));
log('pluckWith, filterWith, add 100, times 2, filter larger than 100, prepend #',
transformInterrestingNumbers(values)); // [ "#202", "#204" ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment