Skip to content

Instantly share code, notes, and snippets.

@AKJAW
Created May 15, 2018 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AKJAW/2616c3875d55b0a9804103ec5924799f to your computer and use it in GitHub Desktop.
Save AKJAW/2616c3875d55b0a9804103ec5924799f to your computer and use it in GitHub Desktop.
const c = console.log
//All for One
function unary(fn) { //przekazuje dalej tylko jeden agrument
return function onlyOneArg(arg){
return fn( arg );
};
}
//c(["1","2","3"].map( ehh )) // [1,NaN,NaN]
//c(["1","2","3"].map( unary( ehh ))) // [1,2,3]
//One on One
function identity(v) {
return v;
}
var words = " Now is the time for all... ".split( /\s|\b/ );
//c(words); // ["","Now","is","the","time","for","all","...",""]
//c(words.filter( identity )); // ["Now","is","the","time","for","all","..."]
function output(msg,formatFn = identity) {
msg = formatFn( msg );
console.log( msg );
}
function upper(txt) {
return txt.toUpperCase();
}
//output( "Hello World", upper ); // HELLO WORLD
//output( "Hello World" ); // Hello World
//Unchanging One
function constant(v) {
return function value(){
return v;
};
}
//p1.then( foo ).then( constant( p2 ) ).then( bar );
//Adapting Arguments to Parameters
function spreadArgs(fn) { //apply
return function spreadFn(argsArr){
return fn( ...argsArr );
};
}
function foo(x,y) {
console.log( x + y );
}
function bar(fn) {
fn( [ 3, 9 ] );
}
//bar( spreadArgs( foo ) ); // 12
function combineFirstTwo([ v1, v2 ]) {
return v1 + v2;
}
function gatherArgs(fn) { //unapply
return function gatheredFn(...argsArr){
return fn( argsArr );
};
}
//c([1,2,3,4,5].reduce( gatherArgs( combineFirstTwo ) )); //15
//Some Now, Some Later
function ajax(url, data, cb){
console.log(url, data, cb)
}
function getPerson(data,cb) {
ajax( "http://some.api/person", data, cb );
}
//getPerson('data', 'cb') //http://some.api/person data cb
function getOrder(data,cb) {
ajax( "http://some.api/order", data, cb );
}
function getCurrentUser(cb) {
getPerson( { user: 123 }, cb );
}
//getCurrentUser('cb') //http://some.api/person {user: "123"} cb
function partial(fn,...presetArgs) {
return function partiallyApplied(...laterArgs){
return fn( ...presetArgs, ...laterArgs );
};
}
//var getPerson = partial( ajax, "http://some.api/person" );
//var getOrder = partial( ajax, "http://some.api/order" );
//c(getPerson)
/*
var getPerson = function partiallyApplied(...laterArgs) {
return ajax( "http://some.api/person", ...laterArgs );
}; */
// version 1/
var getCurrentUser = partial(
ajax,
"http://some.api/person",
{ user: 123 }
);
/*
var getCurrentUser = function partiallyApplied(...laterArgs) {
return ajax(
"http://some.api/person",
{ user: CURRENT_USER_ID },
...laterArgs
);
};
*/
// version 2
var getCurrentUser = partial( getPerson, { user: 123 } );
/*
var getCurrentUser = function outerPartiallyApplied(...outerLaterArgs){
var getPerson = function innerPartiallyApplied(...innerLaterArgs){
return ajax( "http://some.api/person", ...innerLaterArgs );
};
return getPerson( { user: CURRENT_USER_ID }, ...outerLaterArgs );
}
*/
//getCurrentUser()
//c(...[1,2,3]) // 1 2 3
function add(x,y) {
return x + y;
}
/*
c(
[1,2,3,4,5].map( function adder(val){
return add( 3, val );
} )
);// [4,5,6,7,8]*/
//c([1,2,3,4,5].map( partial( add, 3 ) ))// [4,5,6,7,8]
//Reversing Arguments
function reverseArgs(fn) {
return function argsReversed(...args){
return fn( ...args.reverse() );
};
}
var cache = {};
/*najpierw odwracamy ajax, i poprzez partial na pierwszy argument (cb)
dajemy onResult, potem odwracamy spowrotem czyli
url, data, cb(ktory juz jest ustawiony)*/
var cacheResult = reverseArgs(
partial( reverseArgs( ajax ), function onResult(obj){
cache[obj.id] = obj;
} )
);
// later:
//cacheResult( "http://some.api/person", { user: 123 } );
function partialRight(fn,...presetArgs) {
return reverseArgs(
partial( reverseArgs( fn ), ...presetArgs.reverse() )
);
}
var cacheResult = partialRight( ajax, function onResult(obj){
cache[obj.id] = obj;
});
// later:
//cacheResult( "http://some.api/person", { user: 123 } );
function partialRight(fn,...presetArgs) {
return function partiallyApplied(...laterArgs){
return fn( ...laterArgs, ...presetArgs );
};
}
function foo(x,y,z,...rest) {
console.log( x, y, z, rest );
}
var f = partialRight( foo, "z:last" );
//f( 1, 2 ); // 1 2 "z:last" []
//f( 1 ); // 1 "z:last" undefined []
//f( 1, 2, 3 ); // 1 2 3 ["z:last"]
//f( 1, 2, 3, 4 ); // 1 2 3 [4,"z:last"]
//One at a Time
function curry(fn,arity = fn.length) {
return (function nextCurried(prevArgs){
return function curried(nextArg){
var args = [ ...prevArgs, nextArg ];
if (args.length >= arity) {
return fn( ...args );
}
else {
return nextCurried( args );
}
};
})( [] );
}
var curriedAjax = curry( ajax );
var personFetcher = curriedAjax( "http://some.api/person" );
var getCurrentUser = personFetcher( { user: 123 } );
//getCurrentUser( function foundUser(user){ /* .. */ } );
[1,2,3,4,5].map( curry( add )( 3 ) );// [4,5,6,7,8]
var adder = curry( add );
// later
[1,2,3,4,5].map( adder( 3 ) );// [4,5,6,7,8]
function sum(...nums) {
var total = 0;
for (let num of nums) {
total += num;
}
return total;
}
sum( 1, 2, 3, 4, 5 ); // 15
// now with currying:
// (5 to indicate how many we should wait for)
var curriedSum = curry( sum, 5 );
curriedSum( 1 )( 2 )( 3 )( 4 )( 5 ); // 15
//Currying More Than One Argument?
function looseCurry(fn,arity = fn.length) {
return (function nextCurried(prevArgs){
return function curried(...nextArgs){
var args = [ ...prevArgs, ...nextArgs ];
if (args.length >= arity) {
return fn( ...args );
}
else {
return nextCurried( args );
}
};
})( [] );
}
//No Curry for Me, Please
function uncurry(fn) {
return function uncurried(...args){
var ret = fn;
for (let arg of args) {
ret = ret( arg );
}
return ret;
};
}
function sum(...nums) {
var sum = 0;
for (let num of nums) {
sum += num;
}
return sum;
}
var curriedSum = curry( sum, 5 );
var uncurriedSum = uncurry( curriedSum );
//c(curriedSum( 1 )( 2 )( 3 )( 4 )( 5 )); // 15
//c(uncurriedSum( 1, 2, 3, 4, 5 )); // 15
//c(uncurriedSum( 1, 2, 3 )( 4 )( 5 )); // 1
//Order Matters
function partialProps(fn,presetArgsObj) {
return function partiallyApplied(laterArgsObj){
return fn( Object.assign( {}, presetArgsObj, laterArgsObj ) );
};
}
function curryProps(fn,arity = 1) {
return (function nextCurried(prevArgsObj){
return function curried(nextArgObj = {}){
var [key] = Object.keys( nextArgObj );
var allArgsObj = Object.assign(
{}, prevArgsObj, { [key]: nextArgObj[key] }
);
if (Object.keys( allArgsObj ).length >= arity) {
return fn( allArgsObj );
}
else {
return nextCurried( allArgsObj );
}
};
})( {} );
}
function foo({ x, y, z } = {}) {
console.log( `x:${x} y:${y} z:${z}` );
}
var f1 = curryProps( foo, 3 );
var f2 = partialProps( foo, { y: 2 } );
//f1( {y: 2} )( {x: 1} )( {z: 3} );// x:1 y:2 z:3
//f2( { z: 3, x: 1 } );// x:1 y:2 z:3
//Spreading Properties
function spreadArgProps(
fn,
propOrder =
fn.toString()
.replace( /^(?:(?:function.*\(([^]*?)\))|(?:([^\(\)]+?)\s*=>)|(?:\(([^]*?)\)\s*=>))[^]+$/, "$1$2$3" )
.split( /\s*,\s*/ )
.map( v => v.replace( /[=\s].*$/, "" ) )
) {
return function spreadFn(argsObj){
return fn( ...propOrder.map( k => argsObj[k] ) );
};
}
function bar(x,y,z) {
console.log( `x:${x} y:${y} z:${z}` );
}
var f3 = curryProps( spreadArgProps( bar ), 3 );
var f4 = partialProps( spreadArgProps( bar ), { y: 2 } );
//f3( {y: 2} )( {x: 1} )( {z: 3} );// x:1 y:2 z:3
//f4( { z: 3, x: 1 } );// x:1 y:2 z:3
//No Points
function double(x) {
return x * 2;
}
[1,2,3,4,5].map( function mapper(v){
return double( v );
} );// [2,4,6,8,10]
function double(x) {
return x * 2;
}
[1,2,3,4,5].map( double );// [2,4,6,8,10]
// convenience to avoid any potential binding issue
// with trying to use `console.log` as a function
function output(txt) {
console.log( txt );
}
function printIf( predicate, msg ) {
if (predicate( msg )) {
output( msg );
}
}
function isShortEnough(str) {
return str.length <= 5;
}
var msg1 = "Hello";
var msg2 = msg1 + " World";
//printIf( isShortEnough, msg1 ); // Hello
//printIf( isShortEnough, msg2 );
function not(predicate) {
return function negated(...args){
return !predicate( ...args );
};
}
var isLongEnough = not( isShortEnough );
//printIf( isLongEnough, msg1 );
//printIf( isLongEnough, msg2 ); // Hello World
function when(predicate,fn) {
return function conditional(...args){
if (predicate( ...args )) {
return fn( ...args );
}
};
}
var printIf = uncurry( partialRight( when, output ) );
function output(msg) {
console.log( msg );
}
function isShortEnough(str) {
return str.length <= 5;
}
var isLongEnough = not( isShortEnough );
var printIf = uncurry( partialRight( when, output ) );
var msg1 = "Hello";
var msg2 = msg1 + " World";
//printIf( isShortEnough, msg1 ); // Hello
//printIf( isShortEnough, msg2 );
//printIf( isLongEnough, msg1 );
//printIf( isLongEnough, msg2 ); // Hello World
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment