Skip to content

Instantly share code, notes, and snippets.

@mofas
Last active December 11, 2015 07:59
Show Gist options
  • Save mofas/7684a719e58f56a36bd4 to your computer and use it in GitHub Desktop.
Save mofas/7684a719e58f56a36bd4 to your computer and use it in GitHub Desktop.
Show how transducer work.
//We have an array, and we want to modify it to get new value.
const arr = [1, 2, 3];
//f1, f2, f3 are some variable functions will apply to our arr.
const f1 = (x) => x+1;
const f2 = (x) => x*2;
const f3 = (x) => x*x;
// We usually evaluate functions one by one by mapping to get our final answer.
const res1 = arr.map(f1).map(f2).map(f3);
// However, it will generate many intermidate array.
// When array is large, the above function will have poor performance.
// We want visit every element only once, and get the result.
// So we write the following code.
const res2 = arr.reduce(comp1(f1, f2, f3), [])
// How to write a comp1 to make res1 === res2 ?
const comp1 = (f1 , f2, f3) =>{
return (result, x) =>{
return result.push(f3(f2(f1(x))))
}
}
// But this is not flexible enough.
// What if we want the comp1 function that can make the following work
// That is, we want compose function arbitarily
arr.reduce(comp2(f1), [])
arr.reduce(comp2(f1)(comp2(f2)), [])
arr.reduce(comp2(f1)(comp2(f2)(comp2(f3))), [])
// Actually, we need to tell comp2 when to stop waiting new functions and
// start to calculate the result
// The comp2 will be look like this one
// comp2(f1)(endFn)
// comp2(f2)(comp2(f1)(endFn))
// comp2(f1)(comp2(f2)(comp2(f3)(endFn)))
// Q2: write comp2 and endFn
const endFn = (result, x) => {
return result.push(x)
}
// endFn is the function which push our result of each item to final array.
// we can call it append;
const append = endFn = (result, x) => {
return result.push(x)
}
const comp2 = (f) => (combine) => (result, x) =>{
return combine(result, f(x))
}
// Let us to see how this work.
// Take the following function for example:
arr.reduce(comp2(f1)(comp2(f2)(append)), [])
// Firstly, we evaluate the inner function
comp2(f2)(append) = (result, x) => append(result, f2(x))
//Secondly, we substitute it back to original function
comp2(f1)(comp2(f2)(append)) =
(result, x) => combine(result, f1(x)) WHERE combine = append(result, f2(x))
//Finally, we can get
(result, x) => append(result, f2(f1(x)));
//Evaluate append
(result, x) => result.push(f2(f1(x)));
// In other words,
arr.reduce(comp2(f1)(comp2(f2)(append)), [])
// is Equal
arr.reduce((result, x) => result.push(f2(f1(x))), []);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment