gcanti / fp-ts

Functional programming in TypeScript
https://gcanti.github.io/fp-ts/
MIT License
10.63k stars 503 forks source link

Add tapNoneIO for Option, TaskOption and IOOption and tapErrorIO for Either, TaskEither and IOEither #1915

Open iFreilicht opened 7 months ago

iFreilicht commented 7 months ago

🚀 Feature request

Current Behavior

Right now, if I want to log that a function has returned none, there's no tapNone function, I have to do a dance with altW:

   O.altW(() => {
      console.log('My important thing failed!');
      return O.none;
    }),

For Either, tapError requires a similar dance, though for a different reason. It's signature requires a function that returns the same monad, even though the value in that monad isn't used.

  TE.tapError((e) => {
    console.log(`An error occurred: ${e}`);
    return e;  // I could return anything here, as long as it's still a TaskEither. But I can't return nothing
  }

Desired Behavior

I would like to be able to do write code like this

   O.tapXYZ(() => {
      console.log('My important thing failed!')
    }),
  TE.tapXYZ((e) => {
    console.log(`An error occurred: ${e}`);
  }

Suggested Solution

To stay consistent, it seems these should be IO functions. tapNone wouldn't make a lot of sense with the Option-based types (you literally have no input and no output). but tapNoneIO would, and it would allow writing code like this:

   O.tapNoneIO(() => () => {
      console.log('My important thing failed!')
    }),

Similarly, for Either-based types, tapErrorIO would work:

  TE.tapErrorIO((e) => () => {
    console.log(`An error occurred: ${e}`);
  }

It's not perfect, you still need to pass a higher order function, which feels somewhat unnecessary, but it is consistent with tapIO and makes sense in the overall ecosystem.

Who does this impact? Who is this for?

Anyone who wants to perform side-effects on none and left with minimal boilerplate. It is only a quality-of-life improvement, there is no new functionality here.

Describe alternatives you've considered

Your environment

Software Version(s)
fp-ts 2.16.1
TypeScript 5.1.6