0

I am fresh new with the brilliant language-ext c# library.

I have this code that returns a Try<IEnumerable<Try<Unit>> object:

            Try(DetectAlertsToNotify)
            .MapT(SendNotification)
            //treat errors happened indifferently from their source

Edit: DetectAlertsToNotify returns an IEnumerable of AlertDTO

What I would like to achieve is to process elegantly all exceptions or maybe the first exception whatever it happened in DetectAlertsToNotify or SendNotification.

How could I aggregate all errors or take the first error of Try<IEnumerable<Try<Unit>> with keeping code simple and minimum as possible?

maxence51
  • 994
  • 1
  • 8
  • 20
  • Can you give us a little more code to work with? I'm trying to create a working version of your example, but can't find a version of `MapT` that works with `Try`. It looks like `DetectAlertsToNotify` returns `Unit`, right? So `Try(DetectAlertsToNotify)` returns `Try`. I don't see how to invoke `MapT` on that result, though. (I have F#/Haskell experience, but have never used LanguageExt before.) – Brian Berns May 26 '21 at 21:24
  • Thanks, in fact DetectAlertsToNotify returns an IEnumerable – maxence51 May 26 '21 at 21:41
  • OK, but then where does `Try` come from? `Try(DetectAlertsToNotify)` would return a `Try>`, and I still don't see any way to apply `MapT` to that type. – Brian Berns May 26 '21 at 21:45

1 Answers1

2

Maybe you're looking for something like this:

using LanguageExt;
using static LanguageExt.Prelude;

Try<Unit> Send(string message)
{
    return Try(unit);
}

Try<Arr<string>> GetList()
{
    return Try(Array("a", "b", "c"));
}

// LINQ style (better for longer chains)
var errorOrAllResults1 =
    from inputs in GetList()
    from results in inputs.Map(Send).Sequence()
    select results;

// method style
var errorOrAllResults2 = GetList().Bind(inputs => inputs.Map(Send).Sequence());

Notes:

  • I use Arr<T> instead of IEnumerable<T> because this makes sure there is no enumeration outside of Try in case the exception might raise when enumerating. Otherwise we probably need some helper to make sure the enumeration itself is catched in some Try.
  • Sequence() will change inner and outer monad (container). This turns Arr<Try<Unit>> into Try<Arr<Unit>>. We need this because we want/need to "stay" in the Try monad (LINQ expression).

If you look at the intermediate types you probably will get the idea.

stb
  • 772
  • 5
  • 15
  • Thank you very much, this is exactly my case and it is perfect. I was too much focused on using MapT to keep all expressions on the same level. Now I see the point of staying in the same monad with Bind. – maxence51 May 27 '21 at 20:26