Home > Enterprise >  How do I await code inside a method that returns an EitherAsync<T1, T2> in LanguageExt?
How do I await code inside a method that returns an EitherAsync<T1, T2> in LanguageExt?

Time:07-08

When using TryAsync in LanguageExt, you can do something like this...

static TryAsync<int> Divide(int n1, int n2) =>
    TryAsync(async () => {
      // Simulate some async operation that might fail
      await Task.Delay(300);
      return n1 / n2;
    });

I have the need for a similar method that returns an EitherAsync, but I'm stuck, as I can't find a static EitherAsync method to which I can pass an async lambda.

I know I can do this...

static EitherAsync<string, int> Square(int n) =>
  (n * n).AsTask();

...but that doesn't do anything async. If I change it to do this (simulate an async call)...

static EitherAsync<string, int> Square(int n) {
  Task.Delay(300);
  return (n * n).AsTask();
}

...then the call to Task.Delay is not awaited. I can't await it, as I can't make the method async (see this issue for more details).

I might be approaching this wrongly, but I can't see how you can await code inside such a method, which seems odd (to me, but that doesn't prove anything!), as the whole point of this monad is for async code.

Anyone know if it's possible to do something similar for EitherAsync? Thanks

CodePudding user response:

Any function function returning task should work due to implicit casts from T and Task<T> to Either, for example:

static EitherAsync<string, int> Square(int n)
{
    async Task<int> inner()
    {
        await Task.Delay(300);
        return n * n;
    }

    return inner();
}

Or you can manipulate with TryAsync mapping, which, I would say, is more correct approach cause previous one will not handle exceptions thrown during the task execution:

static EitherAsync<string, int> Square2(int n) =>
    new TryAsync<int>(async () =>
        {
            await Task.Delay(300);
            return n * n;
        })
        .ToEither(error => error.Message);

CodePudding user response:

There is an implicit conversion from a Task<T> to an EitherAsync<T, Anything> and an EitherAsync<Anything, T>, so you can just create a Task<T> using Task.Run to run any async code you'd like for example:

static EitherAsync<string, int> Square(int n) =>
    Task.Run(async () => {
        await Task.Delay(300);
        return n * n;
    });
  • Related