1

I have two functions I want to compose.

The first function requires two params. The first param is the date and the second one is the formatter of the date. Something like below:

/*
  Definition of date formats below:
  LTS  : 'h:mm:ss A',
  LT   : 'h:mm A',
  L    : 'MM/DD/YYYY',
  LL   : 'MMMM D, YYYY',
  LLL  : 'MMMM D, YYYY h:mm A',
  LLLL : 'dddd, MMMM D, YYYY h:mm A'
  Pass these into the second parameter of the formatDate function to return the expected date format
 */
export const formatDate = (date = moment(), F = "L") => moment(date).format(F); // F means format refer to the comment above before the function L is the default argument

The second function requires also two params. The first param is the date and the second one is amount of month to be added in the date. Something like this below:

export const addMonth = (date = moment(), amount) => moment(date).add(amount, 'months');.

Now when I test this two functions together using jest.

 expect(
    Util.formatDate(
      Util.addMonth(
        new Date('December 17, 1995 03:24:00'), 1,
      ),
    ),
  ).toEqual("01/17/1996");

Now the test case has passed so everything seems to work fine.

Now I want to use a compose function which compose the function calls and takes the argument and pass the main argument to return the final result.

I found this link that help me with it.

and came up with this code below:

const compose = (...functions) => args => functions.reduceRight((arg, fn) => fn(arg), args);

// Actual test case below:
 expect(
    compose(
      Util.formatDate,
      Util.addMonth,
    )(new Date('February 28, 2018 03:24:00')),
  ).toEqual("03/28/2018");

How can I pass each required arguments in those function calls inside the compose function. Something like this below:

 expect(
    compose(
      (Util.formatDate, "L"),
      (Util.addMonth, 1),
    )(new Date('February 28, 2018 03:24:00')),
  ).toEqual("03/28/2018");

If there's a better implementation to do this you can tell me. Do I need to use some library in order to achieve this?

Appreciate if someone could help Thanks in advance.

1 Answer 1

3

For this to work you need to curry your functions and flip the argument order, because currying usually requires the oposite order:

// reusable combinators

const flip = f => y => x => f(x) (y);
const curry = f => x => y => f(x, y);
const comp = (f, g) => x => f(g(x));

// your functions

const formatDate = (x, y) => `formatDate(${x}, ${y})`;
const addMonth = (x, y) => `addMonth(${x}, ${y})`;

// your functions transformed to be compliant with function composition

const formatDate_ = flip(curry(formatDate));
const addMonth_ = flip(curry(addMonth));

// shows the computational structure

console.log(
  comp(
    formatDate_("F"),
    addMonth_("amount"))
      ("date")); // formatDate(addMonth(date, amount), F)

Now you can see what currying brings you: Easy function composition and partial application for free.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.