Skip to content

Instantly share code, notes, and snippets.

@Phoenix35
Last active June 7, 2018 13:13
Show Gist options
  • Save Phoenix35/f2c23859ec03e154a79d490a6373cd8a to your computer and use it in GitHub Desktop.
Save Phoenix35/f2c23859ec03e154a79d490a6373cd8a to your computer and use it in GitHub Desktop.
// If the Partial Application Syntax is not available, use this
// Code by Kusu
const partialBinder = ((hole, rest) => {
"use strict";
function partiallyBound(fn, args, ...missing) {
const argsLen = args.length;
const missingIter = missing[Symbol.iterator]();
for (let i = 0; i < argsLen; ++i) {
switch (args[i]) {
case hole: break;
case rest: args.splice(i, 1, ...missing); return fn.apply(this, args);
default: continue;
}
const { done, value } = missingIter.next();
args[i] = done ? null : value;
}
return fn.apply(this, args);
}
function partialBinder(fn, ...args) {
let symbolMask = 0;
for (const a of args) {
switch (a) {
case hole:
if (symbolMask & 1) break;
symbolMask |= 0b10;
continue;
case rest:
if (symbolMask & 1) break;
symbolMask |= 0b01;
default:
continue;
}
throw new SyntaxError("illegal parameters");
}
if (symbolMask) return partiallyBound.bind(this, fn, args);
else return fn.bind(this, ...args);
}
return Object.defineProperties(partialBinder, {
hole: { value: hole },
rest: { value: rest },
});
})(Symbol("hole"), Symbol("rest"));
// partialBinder(console.log, 1, partialBinder.hole, 3)(2, 4)
// 1, 2, 3
// partialBinder(console.log, 1, partialBinder.hole, 3, partialBinder.rest)(2, 4)
// 1, 2, 3, 4
// Partial Application Syntax
// console.log(1, ?, 3)(2, 4)
// 1, 2, 3
// console.log(1, ?, 3, ...)(2, 4)
// 1, 2, 3, 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment