Last active
May 18, 2017 07:51
-
-
Save torgeir/f1c09aaee60e302cdbd9 to your computer and use it in GitHub Desktop.
Playing with js combinators.
This file contains hidden or 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 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