Skip to content

Instantly share code, notes, and snippets.

@Avaq
Last active March 5, 2018 12:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Avaq/ffea9ff0cceccaa9d3f1 to your computer and use it in GitHub Desktop.
Save Avaq/ffea9ff0cceccaa9d3f1 to your computer and use it in GitHub Desktop.
Functional JavaScript cookbook
//Combinators
const I = x => x;
//List manipulation
const head = xs => xs[0];
const tail = xs => xs.slice(1);
const append = x => xs => [...xs, x];
//Iteration
const foldl = f => y => xs => xs.length > 0 ? foldl(f)(f(y)(head(xs)))(tail(xs)) : y;
const foldr = f => y => xs => xs.length > 0 ? f(foldr(f)(y)(tail(xs)))(head(xs)) : y;
const map = f => foldl(y => x => append(f(x))(y))([]);
const filter = f => foldl(y => x => f(x) ? append(x)(y) : y)([]);
//Function composition
const compose = f => g => x => f(g(x));
const pipe = foldr(compose)(I);
//Math
const add = a => b => a + b;
const mult = a => b => a * b;
const gt = a => b => b > a;
//Program
pipe([
map(add(1)),
map(mult(2)),
filter(gt(10))
])
([1, 2, 3, 4, 5, 6, 7, 8]);
const noop = B(C(I), I)
const permutations = R.compose(R.sequence(R.of), R.flip(R.repeat));
permutations(2, [1,2,3])
console.clear();
const then = Date.now();
const log = x => console.log(`${Date.now() - then} - ${x}`);
const err = x => console.log(`${Date.now() - then} - ERROR: ${x}`);
const {K, I, pipe} = S;
const {curry, reduce, ap, once, compose, chain, map} = R;
const ftap = f => a => f(a).map(K(a));
//A mock database
const connect = curry(config => Future.cache(Future((rej, res) => (log('Connecting...'), res({name: 'Connection', config})))))
const close = curry(connection => Future((rej, res) => (log(`Closed ${connection.name}`), res(null))))
const query = curry((x, connection) => Future((rej, res) =>
setTimeout(() => (log(`QUERY[${connection.name}][${x}]`), res(eval(x))), 300)
));
const RFuture = Reader.T(Future);
const closeConnection = () => RFuture.ask.chain(pipe([chain(close), RFuture.lift]));
const querySquare = n => RFuture.ask.chain(pipe([chain(query(`${n} * ${n}`)), RFuture.lift]));
RFuture(chain(query('1 + 1')))
.chain(querySquare)
.chain(ftap(closeConnection))
.run(connect({foo: 'bar'}))
.fork(err, log)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment