public static EitherAsync <L, Aff <B> > Traverse <L, A, B>(this Aff <EitherAsync <L, A> > ma, Func <A, B> f) { return(new EitherAsync <L, Aff <B> >(Go(ma, f))); async Task <EitherData <L, Aff <B> > > Go(Aff <EitherAsync <L, A> > ma, Func <A, B> f) { var result = await ma.Run().ConfigureAwait(false); if (result.IsBottom) { return(EitherData <L, Aff <B> > .Bottom); } if (result.IsFail) { return(EitherData.Right <L, Aff <B> >(FailAff <B>(result.Error))); } var db = await result.Value.Data.ConfigureAwait(false); if (db.State == EitherStatus.IsBottom) { return(EitherData <L, Aff <B> > .Bottom); } if (db.State == EitherStatus.IsLeft) { return(EitherData.Left <L, Aff <B> >(db.Left)); } return(EitherData.Right <L, Aff <B> >(SuccessAff <B>(f(db.Right)))); } }
public static TryOptionAsync <Aff <B> > Traverse <A, B>(this Aff <TryOptionAsync <A> > ma, Func <A, B> f) { return(ToTry(() => Go(ma, f))); async Task <OptionalResult <Aff <B> > > Go(Aff <TryOptionAsync <A> > ma, Func <A, B> f) { var ra = await ma.Run().ConfigureAwait(false); if (ra.IsFail) { return(new OptionalResult <Aff <B> >(FailAff <B>(ra.Error))); } var rb = await ra.Value.Try().ConfigureAwait(false); if (rb.IsFaulted) { return(new OptionalResult <Aff <B> >(rb.Exception)); } if (rb.IsNone) { return(OptionalResult <Aff <B> > .None); } return(new OptionalResult <Aff <B> >(SuccessAff <B>(f(rb.Value.Value)))); } }
public static async ValueTask <Aff <B> > Traverse <A, B>(this Aff <ValueTask <A> > ma, Func <A, B> f) { var da = await ma.Run().ConfigureAwait(false); if (da.IsBottom) { throw new BottomException(); } if (da.IsFail) { return(FailAff <B>(da.Error)); } var a = await da.Value.ConfigureAwait(false); return(SuccessAff(f(a))); }
/// <summary> /// Safely use a disposable resource /// </summary> /// <param name="Acq">Acquire resource</param> /// <param name="Use">Use resource</param> public static Aff <R> use <H, R>(Aff <H> Acq, Func <H, Eff <R> > Use) where H : IDisposable => AffMaybe(async() => { var h = await Acq.Run().ConfigureAwait(false); if (h.IsFail) { return(h.Cast <R>()); } try { return(Use(h.Value).Run()); } finally { h.Value?.Dispose(); } });
/// <summary> /// Safely use a disposable resource /// </summary> /// <param name="Acq">Acquire resource</param> /// <param name="Use">Use resource</param> public static Aff <RT, R> use <RT, H, R>(Aff <H> Acq, Func <H, Eff <RT, R> > Use) where RT : struct, HasCancel <RT> where H : IDisposable => AffMaybe <RT, R>(async env => { var h = await Acq.Run().ConfigureAwait(false); if (h.IsFail) { return(h.Cast <R>()); } try { return(Use(h.Value).Run(env)); } finally { h.Value?.Dispose(); } });