Basically, my problem comes down to composing the functionality of several functions of this signature:
(a: A, b: B) => c: C
To simplify, I need to do something like this, where each of a, b, and c are different types:
const upper = (a, b) => {
const c = a.toString().toUpperCase();
return c;
}
const pad = (a, b) => {
const c = a.toString().padStart(2, '0');
return c;
}
const repeat = (a, b) => {
const c = a.toString().repeat(2);
return c;
}
const format = compose(repeat, pad, upper);
For the record b
is used, I'm just omitting it here for simplicity, but assume it must be provided to each function, and each will receive the same value as an argument.
So far, I've been able to solve for the issue of (a, b) => c
not being composable due to the number of arguments by currying the functions, flipping the params, and partially applying b
to each before I compose them:
I'm using standard compose
and flip
utilities like so: https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983
const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);
const flip = fn => a => b => fn(b)(a);
const fnArr = [
repeat,
pad,
upper
];
const makeFormatter = functionArray => (a, b) => {
const flippedAndPartiallyApplied = functionArray.map(fn =>
flip(curry(fn))(b)
);
return compose(...flippedAndPartiallyApplied)(a);
};
const formatter = makeFormatter(fnArr);
So with this, I've gotten the whole b
issue out of the way, and I can compose several unary functions. But my issue remains that each of my functions are a => c
.
Notice how each of my functions must call .toString()
. I need this step before I can modify and return my value. Unfortunately, I need to keep true to each function keeping that same signature.
Is there any way I can further modify each function programatically in a way that I don't need to modify the function source codes, but can mutate them in a way that fits my composition pipeline, or is this just not possible?
I'm working with a API that runs calendar days through a function you provide to the API that can be used to render a day cell to a datepicker UI. This is the API for reference, and this is an example.
I have a use case where I could have multiple renderDay
functions provided through various sources in my app. I'd like to combine these functions somehow because the API only accepts one, and I'd like to do it in an elegant way.