Last active
August 29, 2015 14:23
-
-
Save laser/74dac8642ab1c376f4ef to your computer and use it in GitHub Desktop.
composing non-unary functions
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 async = require('async'); | |
var _ = require('lodash'); | |
var $ = require('./utilities.js'); | |
////////////////////////////////////////////////// | |
// two simple unary functions, for demonstration | |
// purposes | |
function dubble(x) { | |
return x * 2; | |
} | |
function addThree(x) { | |
return x + 3; | |
} | |
// the good stuff below! | |
////////////////////////////////////////////////// | |
// original fn - must introduce an anonymous | |
// expression to work around the fact that we want | |
// to use the expression `n` twice | |
// | |
var lameFn = function(n, callback) { | |
async.compose( | |
$.callbackify(_.last), | |
$.callbackify(_.partial($.report, n)), | |
$.callbackify($.addThree), | |
$.callbackify($.dubble) | |
)(n, callback); | |
} | |
lameFn(10, function(err, output) { | |
assert('Should replicate values to two slots', output === 23); | |
}); | |
////////////////////////////////////////////////// | |
// new - created through composition! | |
// | |
var coolFn = async.compose( | |
$.callbackify(_.last), // return the right side | |
$.callbackify(report), // a binary function: outputs left and right sides | |
_.partial($.secondA, $.callbackify(addThree)), // apply to the right side | |
_.partial($.secondA, $.callbackify(dubble)), // apply to the right side | |
$.callbackify(_.partial($.replicate, 2)) // create an array with left and right sides holding same value | |
); | |
coolFn(10, function(err, output) { | |
assert('Should replicate values to two slots', output === 23); | |
}); |
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 async = require('async'); | |
var _ = require('lodash'); | |
////////////////////////////////////////////////// | |
// for applying two functions (in parallel) over a | |
// two-element array (as close to a bifunctor) as | |
// we're gonna get in this language | |
function bimapA(f1, f2, xs, callback) { | |
async.parallel([ | |
_.partial(f1, xs[0]), | |
_.partial(f2, xs[1]) | |
], callback); | |
} | |
var firstA = _.partial(bimapA, _, callbackify(_.identity)); | |
var secondA = _.partial(bimapA, callbackify(_.identity)); | |
////////////////////////////////////////////////// | |
// transmute a direct-style function to a CPS | |
// function | |
function callbackify (f) { | |
return function callbackifyInner () { | |
var args = _.toArray(arguments); | |
var argsWithoutLast = _.take(args, args.length - 1); | |
var callback = _.last(args);args[args.length - 1]; | |
var result, error; | |
try { | |
result = f.apply(this, argsWithoutLast); | |
} | |
catch (e) { | |
error = e; | |
} | |
callback(error, result); | |
} | |
} | |
function report(xs) { | |
console.log('left: ' + xs[0], 'right: ', xs[1]); | |
return xs; | |
} | |
function assert(msg, expr) { | |
if (!expr) throw msg; | |
console.log('Assertion: ' + msg + ' held true.'); | |
return true; | |
} | |
function replicate(n, x) { | |
var xs = []; | |
while (n--) { | |
xs.push(x); | |
} | |
return xs; | |
} | |
module.exports = { | |
callbackify: callbackify, | |
assert: assert, | |
report: report, | |
replicate: replicate, | |
callbackify: callbackify, | |
bimapA: bimapA, | |
firstA: firstA, | |
secondA: secondA | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment