Skip to content

Latest commit

 

History

History
71 lines (54 loc) · 1.17 KB

transducers.md

File metadata and controls

71 lines (54 loc) · 1.17 KB

Transducers

const curry = fn => (...args) =>
  args.length >= fn.length
    ? fn(...args)
    : curry(fn.bind(undefined, ...args));

const compose = (...fns) => x => fns.reduceRight((v, fn) => fn(v), x);

const mapper = curry(
  (fn, reducer, accumulator, item) =>
    reducer(accumulator, fn(item))
);

const filterer = curry(
  (predicate, reducer, accumulator, item) =>
    predicate(item) ? reducer(accumulator, item) : accumulator
);

const reduce = curry(
  (fn, initialValue, input) =>
    input.reduce(fn, initialValue)
);

const transduce = curry(
  (transducer, reducer, initialValue, input) =>
    reduce(transducer(reducer), initialValue, input)
);

// example

const push = (list, item) => [...list, item];

const sum = (a, b) => a + b;

const isEven = x => x % 2 === 0;

const lte10 = x => x <= 10;

const square = x => x * x;

const add = curry(
  (a, b) => a + b
);

const increment = add(1);

const xform = compose(
  filterer(isEven),
  filterer(lte10),
  mapper(square),
  mapper(increment)
);

transduce(
  xform,
  push,
  [],
  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
)
// [ 1, 5, 17, 37, 65 ]

transduce(
  xform,
  sum,
  0,
  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
)
// 125