Last active
February 19, 2017 02:15
-
-
Save CrossEye/4a4ee819ed8a6fd64f4d to your computer and use it in GitHub Desktop.
Named Curry
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 R = require('./ramda'); | |
// Discussion at https://github.com/ramda/ramda/issues/1258 | |
var namedCurry = function(fn, argNames) { | |
// TODO: what if fn.length != argNames.length? | |
var f = R.curryN(fn.length, function() { | |
return fn.apply(this, arguments); | |
}); | |
f['secret-sauce'] = { | |
argNames: argNames | |
} | |
return f; | |
}; | |
var configure = (function() { | |
var makeArgs = function(inputArgs, argNames, config) { | |
var idx = 0; | |
var outputArgs = []; | |
R.forEach(function(argName) { | |
if (argName in config) { | |
outputArgs.push(config[argName]); | |
} else { | |
outputArgs.push(inputArgs[idx]); | |
idx += 1; | |
// TODO: proper bounds checking. | |
} | |
}, argNames); | |
return outputArgs; | |
}; | |
return function(fn, props) { | |
var sauce = fn['secret-sauce']; | |
if (!sauce) { | |
throw TypeError('Configure called on function without secret sauce'); | |
} | |
var config = R.merge(sauce.config ? sauce.config : {}, props); | |
var argNames = sauce.argNames; | |
var unassigned = R.difference(argNames, R.keys(config)).length; | |
// TODO: what if unassigned is 0? Does this return value or thunk? | |
var f = R.curryN(unassigned, function() { | |
return fn.apply(this, makeArgs(arguments, argNames, config)); | |
}); | |
f['secret-sauce'] = { | |
names: argNames, | |
config: config | |
}; | |
return f; | |
}; | |
}()); | |
var render = function(controller, view, renderImmediately) { | |
return 'v:' + view + ', c: ' + controller + ', ' + (renderImmediately ? 'now' : 'later'); | |
}; | |
var namedRender = namedCurry(render, ['ctrl', 'view', 'immediate']); | |
var modalSignup = configure(namedRender, { | |
ctrl: 'modal', | |
view: 'signup form' | |
}); | |
var login = configure(namedRender, { | |
view: 'login form' | |
}); | |
var modalLogin = login('modal'); | |
render('c1', 'v1', true); //=> "v:navigation-icons, c: sidebar, now" | |
namedRender('c2', 'v2', false); //=> "v:navigation-icons, c: sidebar, later" | |
modalSignup(true); //=> "v:signup form, c: modal, now" | |
login('normal', false); //=> "v:login form, c: normal, later" | |
modalLogin(true); //=> "v:login form, c: modal, now" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment