-
-
Save getify/2875f2e8bd74ced33b81afd6afaae599 to your computer and use it in GitHub Desktop.
transducing even with reducers
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
var filterReducer = pf => cf => (acc,v) => pf(v) ? cf(acc,v) : acc; | |
var mapReducer = mf => cf => (acc,v) => cf(acc,mf(v)); | |
var compose = (...fs) => v => fs.reduceRight((r,f) => f(r),v); | |
var concat = (acc,v) => [ ...acc, v ]; | |
var sum = (x,y) => x + y; | |
// ************************************ | |
var onlyOdds = v => v % 2 == 1; | |
var double = v => v * 2; | |
var onlyHundreds = cf => (vs,v) => v % 10 == 0 ? cf(vs,v * 10) : vs; | |
// ************************************ | |
var list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 20 ]; | |
// ************************************ | |
// OPTION 1 (no transducing) | |
list | |
.filter(onlyOdds) | |
.map(double) | |
.reduce(onlyHundreds(concat),[]); | |
// [ 100, 300 ] | |
list | |
.filter(onlyOdds) | |
.map(double) | |
.reduce(onlyHundreds(sum),0); | |
// 400 |
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
var filterReducer = pf => cf => (acc,v) => pf(v) ? cf(acc,v) : acc; | |
var mapReducer = mf => cf => (acc,v) => cf(acc,mf(v)); | |
var compose = (...fs) => v => fs.reduceRight((r,f) => f(r),v); | |
var concat = (acc,v) => [ ...acc, v ]; | |
var sum = (x,y) => x + y; | |
// ************************************ | |
var onlyOdds = v => v % 2 == 1; | |
var double = v => v * 2; | |
var onlyHundreds = cf => (vs,v) => v % 10 == 0 ? cf(vs,v * 10) : vs; | |
// ************************************ | |
var list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 20 ]; | |
// ************************************ | |
// OPTION 2 (transducing but without including the onlyHundreds(..) reducer) | |
list | |
.reduce( | |
compose( | |
filterReducer(onlyOdds), | |
mapReducer(double) | |
)(concat), | |
[] | |
) | |
.reduce(onlyHundreds(concat),[]); | |
// [ 100, 300 ] | |
list | |
.reduce( | |
compose( | |
filterReducer(onlyOdds), | |
mapReducer(double) | |
)(concat), | |
[] | |
) | |
.reduce(onlyHundreds(sum),0); | |
// 400 |
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
var filterReducer = pf => cf => (acc,v) => pf(v) ? cf(acc,v) : acc; | |
var mapReducer = mf => cf => (acc,v) => cf(acc,mf(v)); | |
var compose = (...fs) => v => fs.reduceRight((r,f) => f(r),v); | |
var concat = (acc,v) => [ ...acc, v ]; | |
var sum = (x,y) => x + y; | |
// ************************************ | |
var onlyOdds = v => v % 2 == 1; | |
var double = v => v * 2; | |
var onlyHundreds = cf => (vs,v) => v % 10 == 0 ? cf(vs,v * 10) : vs; | |
// ************************************ | |
var list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 20 ]; | |
// ************************************ | |
// OPTION 3a (transducing EVEN INCLUDING the onlyHundreds(..) reducer) | |
// **this** is the crazy new invention, an adapter that makes reducers composable | |
// as transducers, similar to how mapReducer(..) and filterReducer(..) do so for | |
// maps and filters, respectively. | |
var reduceReducer = (rf,diff,eq) => cf => (acc,v) => { | |
var res = rf(acc,v); | |
if (!eq(acc,res)) { | |
return cf(acc,diff(acc,res)); | |
} | |
else { | |
return acc; | |
} | |
}; | |
var listDiff = (vs,ws) => ws[ws.length - 1]; | |
var listEq = (vs,ws) => { | |
if (vs.length != ws.length) return false; | |
return (vs[vs.length - 1] === ws[ws.length - 1]); | |
}; | |
var numDiff = (x,y) => y - x; | |
var numEq = (x,y) => x === y; | |
list | |
.reduce( | |
compose( | |
filterReducer(onlyOdds), | |
mapReducer(double), | |
reduceReducer(onlyHundreds(concat),listDiff,listEq) | |
)(concat), | |
[] | |
); | |
// [ 100, 300 ] | |
list | |
.reduce( | |
compose( | |
filterReducer(onlyOdds), | |
mapReducer(double), | |
reduceReducer(onlyHundreds(sum),numDiff,numEq) | |
)(sum), | |
0 | |
); | |
// 400 |
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
var filterReducer = pf => cf => (acc,v) => pf(v) ? cf(acc,v) : acc; | |
var mapReducer = mf => cf => (acc,v) => cf(acc,mf(v)); | |
var compose = (...fs) => v => fs.reduceRight((r,f) => f(r),v); | |
var concat = (acc,v) => [ ...acc, v ]; | |
var sum = (x,y) => x + y; | |
// ************************************ | |
var onlyOdds = v => v % 2 == 1; | |
var double = v => v * 2; | |
var onlyHundreds = cf => (vs,v) => v % 10 == 0 ? cf(vs,v * 10) : vs; | |
// ************************************ | |
var list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 20 ]; | |
// ************************************ | |
// OPTION 3 (transducing EVEN INCLUDING the onlyHundreds(..) reducer) | |
list | |
.reduce( | |
compose( | |
filterReducer(onlyOdds), | |
mapReducer(double), | |
onlyHundreds | |
)(concat), | |
[] | |
); | |
// [ 100, 300 ] | |
list | |
.reduce( | |
compose( | |
filterReducer(onlyOdds), | |
mapReducer(double), | |
onlyHundreds | |
)(sum), | |
0 | |
); | |
// 400 |
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
var compose = (...fs) => v => fs.reduceRight((r,f) => f(r),v); | |
var concat = (acc,v) => [ ...acc, v ]; | |
var sum = (x,y) => x + y; | |
// ************************************ | |
var onlyOdds = v => v % 2 == 1; | |
var double = v => v * 2; | |
// ************************************ | |
var list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 20 ]; | |
// ************************************ | |
// OPTION 4a (transducing by composing ONLY higher-order reducers!) | |
// **this** is the crazy new invention, an adapter that makes reducers composable | |
// as transducers, similar to how mapReducer(..) and filterReducer(..) do so for | |
// maps and filters, respectively. | |
var reduceReducer = (rf,diff,eq) => cf => (acc,v) => { | |
var res = rf(acc,v); | |
if (!eq(acc,res)) { | |
return cf(acc,diff(acc,res)); | |
} | |
else { | |
return acc; | |
} | |
}; | |
var listDiff = (vs,ws) => ws[ws.length - 1]; | |
var listEq = (vs,ws) => { | |
if (vs.length != ws.length) return false; | |
return (vs[vs.length - 1] === ws[ws.length - 1]); | |
}; | |
var numDiff = (x,y) => y - x; | |
var numEq = (x,y) => x === y; | |
list | |
.reduce( | |
compose( | |
reduceReducer((acc,v) => onlyOdds(v) ? [ ...acc, v ] : acc,listDiff,listEq), | |
reduceReducer((acc,v) => [ ...acc, double(v) ],listDiff,listEq), | |
reduceReducer((acc,v) => v % 10 == 0 ? [ ...acc, v * 10 ] : acc,listDiff,listEq) | |
)(concat), | |
[] | |
); | |
// [ 100, 300 ] | |
list | |
.reduce( | |
compose( | |
reduceReducer((acc,v) => onlyOdds(v) ? acc + v : acc,numDiff,numEq), | |
reduceReducer((acc,v) => acc + double(v),numDiff,numEq), | |
reduceReducer((acc,v) => v % 10 == 0 ? acc + (v * 10) : acc,numDiff,numEq) | |
)(sum), | |
0 | |
); | |
// 400 |
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
var compose = (...fs) => v => fs.reduceRight((r,f) => f(r),v); | |
var concat = (acc,v) => [ ...acc, v ]; | |
var sum = (x,y) => x + y; | |
// ************************************ | |
var onlyOdds = v => v % 2 == 1; | |
var double = v => v * 2; | |
// ************************************ | |
var list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 20 ]; | |
// ************************************ | |
// OPTION 4b (transducing by composing ONLY higher-order reducers!) | |
list | |
.reduce( | |
compose( | |
cf => (acc,v) => onlyOdds(v) ? cf(acc,v) : acc, | |
cf => (acc,v) => cf(acc,double(v)), | |
cf => (acc,v) => v % 10 == 0 ? cf(acc,v * 10) : acc | |
)(concat), | |
[] | |
); | |
// [ 100, 300 ] | |
list | |
.reduce( | |
compose( | |
cf => (acc,v) => onlyOdds(v) ? cf(acc,v) : acc, | |
cf => (acc,v) => cf(acc,double(v)), | |
cf => (acc,v) => v % 10 == 0 ? cf(acc,(v * 10)) : acc | |
)(sum), | |
0 | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment