Skip to content

Instantly share code, notes, and snippets.

@thurt
Last active May 8, 2016 23:50
Show Gist options
  • Save thurt/6fe200c80da3d3d2a62f31bcc3944e52 to your computer and use it in GitHub Desktop.
Save thurt/6fe200c80da3d3d2a62f31bcc3944e52 to your computer and use it in GitHub Desktop.
Example usage of a generic pipe and compose
var trace = x => {
console.log(x)
return x
}
var plus1 = x => x + 1
var add2 = (x, y) => x + y
var addList = list => list.reduce(add2, 0)
var concat2 = (x, y) => x.concat(y)
var concatLists = (...lists) => lists.reduce(concat2, [])
/////////////////////////
//var pipe = (...fns) =>
// (...x) =>
// fns.reduce((x, fn) => fn(x), fns.shift()(...x))
var pipe = (...fns) =>
(...x) =>
fns.slice(1).reduce((x, fn) => fn(x), fns[0](...x))
// left-to-right composition
var pipe_GrandSum_plus1 = pipe(concatLists, trace, addList, trace, plus1)
console.log(pipe_GrandSum_plus1([1, 3, 5], [2, 4, 6]))
////////////////////////////
// we can derive compose by reversing fns list
var compose = (...fns) =>
pipe(...fns.reverse())
// right-to-left composition
var comp_GrandSum_plus1 = compose(plus1, trace, addList, trace, concatLists)
console.log(comp_GrandSum_plus1([1, 3, 5], [2, 4, 6]))
////////////////////////////
// Here is the same process in a more classical imperative style
function GrandSum_plus1(...lists) {
var i
var master_list = []
var sum = 0
for (i = 0; i < lists.length; i++) master_list = master_list.concat(lists[i])
console.log(master_list)
for (i = 0; i < master_list.length; i++) sum += master_list[i]
console.log(sum)
return sum + 1
}
console.log(GrandSum_plus1([1, 3, 5], [2, 4, 6]))
/* output :
[ 1, 3, 5, 2, 4, 6 ]
21
22
*/
@thurt
Copy link
Author

thurt commented Apr 26, 2016

Examples for pipe and compose.
pipe performs left-to-right function composition. The leftmost function may have any arity; the remaining functions must be unary.
compose performs right-to-left function composition. The rightmost function may have any arity; the remaining functions must be unary.

Reminder that trace function is unary -- so it should never assume the leftmost position in pipe nor the rightmost position in compose.

@thurt
Copy link
Author

thurt commented May 8, 2016

This pipe function doesn't work for multiple calls to the same return function, because it mutates the fns array:

var pipe = (...fns) =>
  (...x) =>
    fns.reduce((x, fn) => fn(x), fns.shift()(...x))

So here is a fixed version:

var pipe = (...fns) =>
  (...x) =>
    fns.slice(1).reduce((x, fn) => fn(x), fns[0](...x))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment