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?
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:
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.