Created
May 17, 2018 11:38
-
-
Save AKJAW/db2f54959302c081ca5273c692f3efb5 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 | |
function partialRight(fn,...presetArgs) { | |
return function partiallyApplied(...laterArgs){ | |
return fn( ...laterArgs, ...presetArgs ); | |
}; | |
} | |
function reverseArgs(fn) { | |
return function argsReversed(...args){ | |
return fn( ...args.reverse() ); | |
}; | |
} | |
function partial(fn,...presetArgs) { | |
return function partiallyApplied(...laterArgs){ | |
return fn( ...presetArgs, ...laterArgs ); | |
}; | |
} | |
//Output to Input | |
function words(str) { | |
return String( str ) | |
.toLowerCase() | |
.split( /\s|\b/ ) | |
.filter( function alpha(v){ | |
return /^[\w]+$/.test( v ); | |
} ); | |
} | |
function unique(list) { | |
var uniqList = []; | |
for (let v of list) { | |
// value not yet in the new list? | |
if (uniqList.indexOf( v ) === -1 ) { | |
uniqList.push( v ); | |
} | |
} | |
return uniqList; | |
} | |
var text = "To compose two functions together, pass the \ | |
output of the first function call as the input of the \ | |
second function call."; | |
var wordsFound = words( text ); | |
var wordsUsed = unique( wordsFound ); | |
wordsUsed; | |
// ["to","compose","two","functions","together","pass", | |
// "the","output","of","first","function","call","as", | |
// "input","second"] | |
function uniqueWords(str) { | |
return unique( words( str ) ); | |
} | |
//Machine Making | |
function compose2(fn2,fn1) { | |
return function composed(origValue){ | |
return fn2( fn1( origValue ) ); | |
}; | |
} | |
var uniqueWords = compose2( unique, words ); | |
var letters = compose2( words, unique ); | |
var chars = letters( "How are you Henry?" ); | |
chars; | |
// ["h","o","w","a","r","e","y","u","n"] | |
//General Composition | |
function compose(...fns) { | |
return function composed(result){ | |
// copy the array of functions | |
var list = [...fns]; | |
while (list.length > 0) { | |
// take the last function off the end of the list | |
// and execute it | |
result = list.pop()( result ); | |
} | |
return result; | |
}; | |
} | |
function skipShortWords(words) { | |
var filteredWords = []; | |
for (let word of words) { | |
if (word.length > 4) { | |
filteredWords.push( word ); | |
} | |
} | |
return filteredWords; | |
} | |
var text = "To compose two functions together, pass the \ | |
output of the first function call as the input of the \ | |
second function call."; | |
var biggerWords = compose( skipShortWords, unique, words ); | |
var wordsUsed = biggerWords( text ); | |
//c(wordsUsed); | |
// ["compose","functions","together","output","first", | |
// "function","input","second"] | |
// Note: uses a `<= 4` check instead of the `> 4` check | |
// that `skipShortWords(..)` uses | |
function skipLongWords(words) { | |
var filteredWords = []; | |
for (let word of words) { | |
if (word.length <= 4) { | |
filteredWords.push( word ); | |
} | |
} | |
return filteredWords; | |
} | |
var filterWords = partialRight( compose, unique, words ); | |
var biggerWords = filterWords( skipShortWords ); | |
var shorterWords = filterWords( skipLongWords ); | |
biggerWords( text ); | |
// ["compose","functions","together","output","first", | |
// "function","input","second"] | |
shorterWords( text ); | |
// ["to","two","pass","the","of","call","as"] | |
//Alternative Implementationss | |
function compose(...fns) { | |
return function composed(result){ | |
return [...fns].reverse().reduce( function reducer(result,fn){ | |
return fn( result ); | |
}, result ); | |
}; | |
} | |
//ostatnia wywołana funkcja moze przyjmować wiele argumentów | |
function compose(...fns) { | |
return fns.reverse().reduce( function reducer(fn1,fn2){ | |
//argumenty w ostatniej funckji ['sdasd', 'asds'] | |
return function composed(...args){ | |
return fn2( fn1( ...args ) ); | |
}; | |
} ); | |
} | |
//var biggerWords = compose( skipShortWords, unique, words ); | |
//console.log(biggerWords) | |
//biggerWords('sdasd', 'asds') | |
function compose(...fns) { | |
// pull off the last two arguments | |
var [ fn1, fn2, ...rest ] = fns.reverse(); | |
var composedFn = function composed(...args){ | |
return fn2( fn1( ...args ) ); | |
}; | |
if (rest.length == 0) return composedFn; | |
return compose( ...rest.reverse(), composedFn ); | |
} | |
//Reordered Composition | |
function pipe(...fns) { | |
return function piped(result){ | |
var list = [...fns]; | |
while (list.length > 0) { | |
// take the first function from the list | |
// and execute it | |
result = list.shift()( result ); | |
} | |
return result; | |
}; | |
} | |
var pipe = reverseArgs( compose ); | |
var filterWords = partialRight( compose, unique, words ); | |
// vs | |
var filterWords = partial( pipe, words, unique ); //szybsze | |
//Abstraction | |
function saveComment(txt) { | |
if (txt != "") { | |
comments[comments.length] = txt; | |
} | |
} | |
function trackEvent(evt) { | |
if (evt.name !== undefined) { | |
events[evt.name] = evt; | |
} | |
} | |
function storeData(store,location,value) { | |
store[location] = value; | |
} | |
function saveComment(txt) { | |
if (txt != "") { | |
storeData( comments, comments.length, txt ); | |
} | |
} | |
function trackEvent(evt) { | |
if (evt.name !== undefined) { | |
storeData( events, evt.name, evt ); | |
} | |
} | |
//Separation Enables Focus | |
function getData() { | |
return [1,2,3,4,5]; | |
} | |
// imperative | |
var tmp = getData(); | |
var a = tmp[0]; | |
var b = tmp[3]; | |
// declarative | |
var [ a ,,, b ] = getData(); | |
//Composition as Abstraction | |
// imperative | |
function shorterWords(text) { | |
return skipLongWords( unique( words( text ) ) ); | |
} | |
// declarative | |
var shorterWords = compose( skipLongWords, unique, words ); | |
//Revisiting Points | |
function ajax(url, data, cb) { | |
c('ajax', url, data, cb) | |
if(url === 'http://some.api/order'){ | |
const person = {personId: 10} | |
cb(person) | |
} else { | |
const person = {name: 'pawel'} | |
cb(person) | |
} | |
} | |
function output(txt) { | |
console.log( txt ); | |
} | |
function extractName(person) { | |
return person.name; | |
} | |
function prop(name,obj) { | |
//debugger | |
return obj[name]; | |
} | |
function setProp(name,obj,val) { | |
var o = Object.assign( {}, obj ); | |
o[name] = val; | |
return o; | |
} | |
function makeObjProp(name,value) { | |
return setProp( name, {}, value ); | |
} | |
var getPerson = partial( ajax, "http://some.api/persons" ); | |
var getLastOrder = partial( ajax, "http://some.api/order", { id: -1 } ); | |
/* | |
getLastOrder( function orderFound(order){ | |
getPerson( { id: order.personId }, function personFound(person){ | |
output( person.name ); | |
} ); | |
} ); | |
*/ | |
var extractName = partial( prop, "name" ); | |
var outputPersonName = compose( output, extractName ); | |
var processPerson = partialRight( getPerson, outputPersonName ); | |
var personData = partial( makeObjProp, "id" ); | |
var extractPersonId = partial( prop, "personId" ); | |
var lookupPerson = | |
compose( processPerson, personData, extractPersonId ); | |
//getLastOrder( lookupPerson ); | |
c(compose(x => x+1, y => y+2, z=> z*3)(0)) //0*3=>0+2=>2+1 = 3 | |
c(pipe(x => x+1, y => y+2, z=> z*3)(0)) // 0+1=>1+2=>3*3 = 9 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment