π Give `map` the same overloaded signature as `flatMap`
patstockwell opened this issue Β· comments
π Hello
Hi, my name is Patrick. Thanks for all your hard work maintaining fp-ts
. I use this library daily at work and have seen steady adoption of FP from broader parts of the engineering community at my workplace, in no small part to your work. Thank you.
π Feature request
I would like map
to have the same overloaded signature as flatMap
.
Taking Option
as an example,
const op: Option<number> = Some(8);
O.flatMap
can be called with the Option first:
flatMap(op, num => num > 0 ? : Some(num) : None);
Or with the function first:
flatMap((n: number) => n > 0 ? some(n) : none)(op),
π Current Behavior
Right now, map only supports function first.
map((n: number) => n + 1)(op);
We can use pipe
to invert the signature like so:
pipe(op, map((n) => n + 1));
but it would be nice to have this built into the signature.
π Desired Behavior
I would like to be able to call map
with the function in the second position. As an example, this would be useful for the last step when nesting, like so:
declare const getName: () => Option<string>;
declare const getGreeting: () => Option<string>;
const welcome: Option<string> =
flatMap(getName(), name => (
map(getGreeting(), greeting => (
`${greeting}, ${name}!`
))
));
π¦ Suggested Solution
Here is a suggestion based on one module (Option
):
Update the map signature to use dual
and allow both signatures like the way that flatMap
is defined:
Lines 413 to 416 in 01b8661
Here is the current signature.
Lines 336 to 337 in 01b8661
Perhaps this could be...
export const map: {
<A, B>(f: (a: A) => B): (ma: Option<A>) => Option<B>
<A, B>(ma: Option<A>, f: (a: A) => B): Option<B>
} = /*#__PURE__*/ dual(2, <A, B>(ma: Option<A>, f: (a: A) => B): Option<B> => (isNone(ma) ? none : some(f(ma.value))))
π¦ Who does this impact? Who is this for?
I think this would help all users. I also think it would help adoption if new users can apply the same mental model (the same signature) for multiple functions.
πͺΌDescribe alternatives you've considered
An alternative is to use pipe
to flip the order of arguments around.
π‘ Additional context
I have not audited all the modules, but map
exists in quite a few places (Option
, Either
, IO
, Task
, TaskEither
for starters). I don't know how disruptive a change in one module might be to other modules.
π¦ Your environment
Software | Version(s) |
---|---|
fp-ts | 2.16 |
TypeScript | 5.1.6 |
Thank you!
The flatMap
function was added recently and already in its current dual function form, while the map
function has been around for a long time. It would be too risky, in terms of unwanted breaking changes, to change its signature.
No problems, that makes sense. Let's leave it as is. Thanks for your thoughts!