Skip to content

Instantly share code, notes, and snippets.

@gabejohnson
Last active December 19, 2018 16:52
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 gabejohnson/b8c0952497f43fdabe6c34a0c88dda1f to your computer and use it in GitHub Desktop.
Save gabejohnson/b8c0952497f43fdabe6c34a0c88dda1f to your computer and use it in GitHub Desktop.
Because I'm lazy and mixfix w/ proxies is slow
var isWrapper = Symbol('isWrapper');
function _(arg, args=[], ops=[]) {
const myArgs = args.concat([arg]);
const myOps = ops.slice(0);
const f = ([op]) => (
myOps.push(op),
wrap(arg2 => _(arg2, myArgs, myOps), myArgs, myOps)
);
Object.keys(_).forEach(n => {
Object.defineProperty(f, n, {
get: () => f([n])
});
});
return wrap(f, myArgs, myOps);
}
var wrap = (f, args, ops) => {
Object.defineProperty(f, '_', {
get: () => runProgram(args.slice(0), ops.slice(0))
});
Object.defineProperty(f, isWrapper, {
value: true
});
return f;
};
// apply :: ((a => b), a) => b
var apply = (f, a) => f(a);
// applyArgs :: Array Any => (Any, String) => Any
var applyArgs = args => (result, c) => {
// unbox
if (result[isWrapper]) result = result._;
result = _[c] (result);
if (args.length > 0) {
// unbox
var arg = args.shift();
if (arg[isWrapper]) arg = arg._;
return result (arg);
}
return result;
};
// runProgram :: Program => Any
var runProgram = (args, calls) => calls.reduce(applyArgs(args), args.shift());
// mixfix :: Array String => Function => Function
var infix = ([pattern]) => f => _[pattern] = f;
// importLib :: StrMap Function => Effect Unit
var importLib = lib => Object.keys(lib).forEach(k => {
if (_[k] == null
&& typeof lib[k] === 'function'
&& lib[k].length === 2) {
_[k] = lib[k];
}
});
// map :: (a => b) => Array a => Array b
infix `map` (f => xs => xs.map(f));
// ap :: Array (a => b) => Array a => Array b
infix `ap` (fs => xs => fs.reduce((acc, f) => acc.concat(xs.map(f)), []));
_(x => y => x + y)`map`([1,2,3])`ap`([4,5,6])._;
// pipe :: a => (a => b) => b
infix `pipe` (x => f => f(x));
// inc :: Number => Number
var inc = x => x + 1;
_(0)
.pipe(inc)
.pipe(inc)
.pipe(inc)._; // 3
infix `` (xs => ys => xs.concat(ys));
_([1,2,3]) `` ([4,5,6])._;
infix `$` (_.map);
infix `*` (_.ap);
_(x => y => z => x + y + z) `$` ([1,2,3]) `*` ([4,5,6]) `*` ([7,8,9])._;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment