JSFiddle - React, Tailwind, and code Playground
JavaScript
const mutualRecursion = (...fs) => fs.map(f => f(...fs));
const makeCounterBase = () => {
let counter = 0;
return {
get: (g, s, i) => () => counter,
set: (g, s, i) => value => counter = value,
inc: (g, s, i) => () => s(g, s, i)(g(g, s, i)()+1)
};
};
const makeCounter = () => {
const base = makeCounterBase();
const [get, set, inc] = mutualRecursion(base.get, base.set, base.inc);
return {
get,
set,
inc
};
};
const makeLoggingCounter = () => {
const base = makeCounterBase();
const [get, set, inc] = mutualRecursion(
(g, s, i) => () => { console.log('get!'); return base.get(g, s, i)(); },
(g, s, i) => value => { console.log('set!'); return base.set(g, s, i)(value); },
(g, s, i) => () => { console.log('inc!'); return base.inc(g, s, i)(); }
);
return {
get,
set,
inc
};
}
const counter1 = makeCounter();
console.log('Calling get()');
console.log(counter1.get());
console.log('Calling set(2)');
counter1.set(2);
console.log('Calling get()');
console.log(counter1.get());
console.log('Calling inc()');
counter1.inc();
console.log('Calling get()');
console.log(counter1.get());
const counter2 = makeLoggingCounter();
console.log('Calling get()');
console.log(counter2.get());
console.log('Calling set(2)');
counter2.set(2);
console.log('Calling get()');
console.log(counter2.get());
console.log('Calling inc()');
counter2.inc();
console.log('Calling get()');
console.log(counter2.get());