Created
May 15, 2018 17:50
-
-
Save AKJAW/2616c3875d55b0a9804103ec5924799f to your computer and use it in GitHub Desktop.
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
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