3 ms·
Actually this doesn't really capture the idea properly - you need a "reducerComposer" function that can compose any functions that look like mySumReducer / myTi
by defen 12y ago
Actually this doesn't really capture the idea properly - you need a "reducerComposer" function that can compose any functions that look like mySumReducer / myTimesReducer (take a memo and a value). You've just manually composed them in myDoublingTransducer, which indeed is just straight function composition. Your reducerComposer needs to function if the first reducer returns nothing (e.g. filter) or multiple values (e.g. flattening a list of lists). One way to think of it is that you are "pushing" values through a chain of reducers, and at any step you might produce 0, 1, or multiple values for the next step.
- ww520 12y agoSorry I was editing before I saw your comment. Note: There was a myDoublingTransducer before. On a separate note, a reducer returns nothing doesn't make sense. A reducer might not add the current value to the memo (filter) but it always returns some memo for the next step. Also a reducer would not return multiple values. It returns just one value, the memo. If there are multiple values produced at a step, they would have been added to the memo. The function signature of a reducer is (s,v)->s, that means it always returns one thing.
- defen 12y ago> A reducer might not add the current value to the memo (filter) but it always returns some memo for the next step. I think the idea is that your reducer function shouldn't have to care about steps or memos. e.g. I should be able to do filter(function(x) { return x < 10; }); and get back some thing that I can then pass in to map, or to reduce, or compose with other things.
- ww520 12y agoHmm, isn't that just the filter predicate function? Not the reducer itself? Looks like the filter() function constructs a reducer using the predicate. The new reducer adds the filtering functionality with the predicate. Looking at the code for filter (copied from above) filter: ([pred] (fn [f1] <-- builds the new reducer; f1 is the inner reducer (fn <-- this is the new outer reducer ([result input] <-- outer's params: result is memo; input is value (if (pred input) <-- pred is user provided, your function (f1 result input) <-- calls the inner reducer; returns its result. result))))) <-- call filtered, returns result unchanged. The reducer still behaves as reducer, returning one result. A Javascript version would be: function filterTransducer(innerReducer, pred) { return function(memo, value) { if (pred(value)) return innerReducer(memo, value) return memo; } }