Last active
December 19, 2018 16:52
-
-
Save gabejohnson/b8c0952497f43fdabe6c34a0c88dda1f to your computer and use it in GitHub Desktop.
Because I'm lazy and mixfix w/ proxies is slow
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 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