Last active
December 11, 2015 07:59
-
-
Save mofas/7684a719e58f56a36bd4 to your computer and use it in GitHub Desktop.
Show how transducer work.
This file contains hidden or 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
//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