Advanced Functional Patterns — Series 2

Preview — 3 of 10 questions

javascript
const Right = value => ({ map: fn => Right(fn(value)), fold: (_, g) => g(value) });
const Left = error => ({ map: () => Left(error), fold: f => f(error) });
const safeDivide = (a, b) => (b === 0 ? Left('Division by zero') : Right(a / b));

const result = safeDivide(10, 0)
  .map(x => x * 2)
  .fold(
    err => `Error: ${err}`,
    val => `Result: ${val}`,
  );
console.log(result);
AResult: Infinity
BError: undefined
CError: Division by zero
DThrows a TypeError because dividing by zero is invalid

javascript
function trampoline(fn) {
  return (...args) => {
    let result = fn(...args);
    while (typeof result === 'function') result = result();
    return result;
  };
}
function sum(n, acc = 0) {
  if (n === 0) return acc;
  return () => sum(n - 1, acc + n);
}
const safeSum = trampoline(sum);
console.log(safeSum(100000));
ARangeError: Maximum call stack size exceeded, same as unguarded recursion
Bundefined
C100000
D5000050000

javascript
function addCPS(a, b, callback) { callback(a + b); }
function multiplyCPS(a, b, callback) { callback(a * b); }
addCPS(2, 3, sum => multiplyCPS(sum, 10, product => console.log(product)));
A50 — this is Continuation-Passing Style: instead of returning a value, each function accepts a callback ("continuation") that describes what to do with the result next
B5, demonstrating currying
C10, demonstrating memoization
DTypeError: callback is not a function

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.