How to properly curry with ES6?

Viewed 149

Say I have,

const toUpperCase = word => word.toUpperCase();
const reverse = word => word.split('').reverse().join('')
const toLowerCase = word => word.toLowerCase();

How can I do something like,

const transformWord = word => toUpperCase(word) => reverse(word) => toLowerCase(word)
console.log(transformWord('abcdefg')) // expected output: gfedcba
5 Answers

You could use an array of the functions and reduce over them:

const toUpperCase = word => word.toUpperCase();
const reverse = word => word.split('').reverse().join('')
const toLowerCase = word => word.toLowerCase();

const transformWord = word => [toUpperCase, reverse, toLowerCase].reduce((lastVal, fn) => fn(lastVal), word);
console.log(transformWord('abcdefg')) // expected output: gfedcba

There's also the pipeline operator proposal which makes this look a whole lot neater, but that's ages away from being implemented (it's still stage 1):

const transformWord = word => word |> toUpperCase |> reverse |> toLowerCase;

You could take a pipe function which reduces the given function by using a parameter.

const
    pipe = (...functions) => input => functions.reduce((acc, fn) => fn(acc), input),
    toUpperCase = word => word.toUpperCase(),
    reverse = word => word.split('').reverse().join(''),
    toLowerCase = word => word.toLowerCase(),
    transformWord = pipe(toUpperCase, reverse, toLowerCase);


console.log(transformWord('abcdefg')) // expected output: gfedcba

I don't see what this has to do with currying. I think you're just looking for function composition:

const transformWord = word => toLowerCase(reverse(toUpperCase(word)))
const toUpperCase = word => word.toUpperCase();
const reverse = word => word.split('').reverse().join('')
const toLowerCase = word => word.toLowerCase();

const transformWord = word => toLowerCase(reverse(toUpperCase(word)));
console.log(transformWord('abcdefg')) //Output: gfedcba

Use recursive approach to write curry function. Curry function returns a function if you pass the transform function and when you pass the word, it will all the transformations and return the result word. Only thing last has to be word.

transformWord(processA)(processB)(processN)(word)

const toUpperCase = word => word.toUpperCase();
const reverse = word => word.split('').reverse().join('')
const toLowerCase = word => word.toLowerCase();

const transformWord = arg => {
  const queue = [arg];

  const curry = item => {
    if (typeof item === "string") {
      let word = item;
      while (queue.length > 0) {
        const transform = queue.shift();
        word = transform(word);
      }
      return word;
    } else {
      queue.push(item);
      return curry;
    }
  };
  return curry;
};

console.log(transformWord(toUpperCase)(reverse)(toLowerCase)("abcdefg"));
console.log(transformWord(toUpperCase)("abcdefg"));

Related