lean-mind / monads

A set of monads created with typescript using an OOP approach
MIT License
5 stars 2 forks source link

Support asynchrony #15

Closed Marius9595 closed 3 days ago

Wolfremium13 commented 5 days ago

Hello, how's it going? I was thinking about trying to support the interoperability of Either functions, which are synchronous, with Future functions. For this, I was inspired by the .toAsync method from LanguageExt.Core, which allows converting an Either into one that supports asynchrony. In our case, we have the Future component. Here's an example case:

  it.each([
    {
      type: 'Right',
      either: Either.right(2),
      syncClosure: (x: number) => x * 2,
      asyncClosure: async (x: number) => x * 2,
      expected: 8,
    },
  ])(
    '$type should handle map with another async map operation correctly',
    async ({ either, syncClosure, asyncClosure, expected }) => {
      either
        .map(syncClosure)
        .toPromise()
        .map(asyncClosure)
        .complete(
          async (value) => expect(await value).toEqual(expected),
          async (error) => expect(error).toBeUndefined()
        );
    }
  );

Where in abstract class we add:

// abstract class Either<L, R>
abstract toPromise(): Future<R | L>;

And in its implementations:

// class Left<L, R>
toPromise(): Future<L> {
    return Future.of(() => Promise.resolve(this.value));
}
// class Right<L, R>
toPromise(): Future<R> {
    return Future.of(() => Promise.resolve(this.value));
}

I'm no expert in this field, but I find it interesting to be able to chain synchrony with asynchrony, giving the latter the possibility to have previous asynchronous calls. Let me know if you have any feedback.

Marius9595 commented 3 days ago

Hi @Wolfremium13!

Thanks for your proposal! :D

The approach is interesting. To keep something like the pipeline of transformations you propose is something that we want to.

The usage of Future sounds good because we could avoid the duplication of monads such as Eitherwith EitherAsync. Although I am a little concerning about some method names:

What do you think @myugen? This proposal allows creating a pipeline of transformation with sync and async stuff, for me the main requirement.