Пример #1
0
 public static TryOption <Eff <B> > Traverse <A, B>(this Eff <TryOption <A> > ma, Func <A, B> f) => () =>
 {
     var mb = ma.Run();
     if (mb.IsBottom)
     {
         return(OptionalResult <Eff <B> > .None);
     }
     if (mb.IsFail)
     {
         return(new OptionalResult <Eff <B> >(FailEff <B>(mb.Error)));
     }
     var mr = mb.Value.Try();
     if (mr.IsBottom)
     {
         return(OptionalResult <Eff <B> > .None);
     }
     if (mr.IsFaulted)
     {
         return(new OptionalResult <Eff <B> >(mr.Exception));
     }
     if (mr.IsNone)
     {
         return(OptionalResult <Eff <B> > .None);
     }
     return(new OptionalResult <Eff <B> >(SuccessEff <B>(f(mr.Value.Value))));
 };
Пример #2
0
        public static TryOptionAsync <Eff <B> > Traverse <A, B>(this Eff <TryOptionAsync <A> > ma, Func <A, B> f)
        {
            return(ToTry(() => Go(ma, f)));

            async Task <OptionalResult <Eff <B> > > Go(Eff <TryOptionAsync <A> > ma, Func <A, B> f)
            {
                var ra = ma.Run();

                if (ra.IsFail)
                {
                    return(new OptionalResult <Eff <B> >(FailEff <B>(ra.Error)));
                }
                var rb = await ra.Value.Try().ConfigureAwait(false);

                if (rb.IsFaulted)
                {
                    return(new OptionalResult <Eff <B> >(rb.Exception));
                }
                if (rb.IsNone)
                {
                    return(OptionalResult <Eff <B> > .None);
                }
                return(OptionalResult <Eff <B> > .Some(SuccessEff <B>(f(rb.Value.Value))));
            }
        }
Пример #3
0
 /// <summary>
 /// Create a new cancellation context and run the provided Aff in that context
 /// </summary>
 /// <param name="ma">Operation to run in the next context</param>
 /// <typeparam name="RT">Runtime environment</typeparam>
 /// <typeparam name="A">Bound value type</typeparam>
 /// <returns>An asynchronous effect that captures the operation running in context</returns>
 public static Eff <RT, A> localCancel <RT, A>(Eff <RT, A> ma) where RT : struct, HasCancel <RT> =>
 EffMaybe <RT, A>(rt =>
 {
     var rt1 = rt.LocalCancel;
     using (rt1.CancellationTokenSource)
     {
         return(ma.ReRun(rt1));
     }
 });
Пример #4
0
        public static async ValueTask <Eff <B> > Traverse <A, B>(this Eff <ValueTask <A> > ma, Func <A, B> f)
        {
            var mr = ma.Run();

            if (mr.IsBottom)
            {
                return(FailEff <B>(BottomException.Default));
            }
            else if (mr.IsFail)
            {
                return(FailEff <B>(mr.Error));
            }
            return(SuccessEff <B>(f(await mr.Value.ConfigureAwait(false))));
        }
Пример #5
0
        public static Validation <Fail, Eff <B> > Traverse <Fail, A, B>(this Eff <Validation <Fail, A> > ma, Func <A, B> f)
        {
            var tres = ma.Run();

            if (tres.IsBottom || tres.IsFail)
            {
                return(Validation <Fail, Eff <B> > .Success(FailEff <B>(tres.Error)));
            }
            else if (tres.Value.IsFail)
            {
                return(Validation <Fail, Eff <B> > .Fail((Seq <Fail>) tres.Value));
            }
            else
            {
                return(Validation <Fail, Eff <B> > .Success(SuccessEff(f((A)tres.Value))));
            }
        }
Пример #6
0
 /// <summary>
 /// Safely use a disposable resource
 /// </summary>
 /// <param name="Acq">Acquire resource</param>
 /// <param name="Use">Use resource</param>
 public static Eff <R> use <H, R>(Eff <H> Acq, Func <H, Eff <R> > Use) where H : IDisposable =>
 EffMaybe(() =>
 {
     var h = Acq.ReRun();
     if (h.IsFail)
     {
         return(h.Cast <R>());
     }
     try
     {
         return(Use(h.Value).Run());
     }
     finally
     {
         h.Value?.Dispose();
     }
 });
Пример #7
0
 /// <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>(Eff <H> Acq, Func <H, Aff <R> > Use) where H : IDisposable =>
 AffMaybe(async() =>
 {
     var h = Acq.ReRun();
     if (h.IsFail)
     {
         return(h.Cast <R>());
     }
     try
     {
         return(await Use(h.Value).Run().ConfigureAwait(false));
     }
     finally
     {
         h.Value?.Dispose();
     }
 });
Пример #8
0
 /// <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>(Eff <H> Acq, Func <H, Aff <RT, R> > Use)
     where RT : struct, HasCancel <RT>
     where H : IDisposable =>
 AffMaybe <RT, R>(async env =>
 {
     var h = Acq.ReRun();
     if (h.IsFail)
     {
         return(h.Cast <R>());
     }
     try
     {
         return(await Use(h.Value).Run(env).ConfigureAwait(false));
     }
     finally
     {
         h.Value?.Dispose();
     }
 });
Пример #9
0
 /// <summary>
 /// Safely use a disposable resource
 /// </summary>
 /// <param name="Acq">Acquire resource</param>
 /// <param name="Use">Use resource</param>
 public static Eff <RT, R> use <RT, H, R>(Eff <H> Acq, Func <H, Eff <RT, R> > Use)
     where RT : struct, HasCancel <RT>
     where H : IDisposable =>
 EffMaybe <RT, R>(env =>
 {
     var h = Acq.ReRun();
     if (h.IsFail)
     {
         return(h.Cast <R>());
     }
     try
     {
         return(Use(h.Value).Run(env));
     }
     finally
     {
         h.Value?.Dispose();
     }
 });
Пример #10
0
        public static Option <Eff <B> > Traverse <A, B>(this Eff <Option <A> > ma, Func <A, B> f)
        {
            var tres = ma.Run();

            if (tres.IsBottom)
            {
                return(None);
            }
            else if (tres.IsFail)
            {
                return(Some(FailEff <B>(tres.Error)));
            }
            else if (tres.Value.IsNone)
            {
                return(None);
            }
            else
            {
                return(Some(SuccessEff(f(tres.Value.Value))));
            }
        }
Пример #11
0
        public static EitherUnsafe <L, Eff <B> > Traverse <L, A, B>(this Eff <EitherUnsafe <L, A> > ma, Func <A, B> f)
        {
            var tres = ma.Run();

            if (tres.IsBottom)
            {
                return(EitherUnsafe <L, Eff <B> > .Bottom);
            }
            else if (tres.IsFail)
            {
                return(RightUnsafe(FailEff <B>(tres.Error)));
            }
            else if (tres.Value.IsLeft)
            {
                return(EitherUnsafe <L, Eff <B> > .Left((L)tres.Value));
            }
            else
            {
                return(EitherUnsafe <L, Eff <B> > .Right(SuccessEff(f((A)tres.Value))));
            }
        }
Пример #12
0
        public static EitherAsync <L, Eff <B> > Traverse <L, A, B>(this Eff <EitherAsync <L, A> > ma, Func <A, B> f)
        {
            try
            {
                return(new EitherAsync <L, Eff <B> >(Go(ma, f)));

                async Task <EitherData <L, Eff <B> > > Go(Eff <EitherAsync <L, A> > ma, Func <A, B> f)
                {
                    var ra = ma.Run();

                    if (ra.IsBottom)
                    {
                        return(EitherData <L, Eff <B> > .Bottom);
                    }
                    if (ra.IsFail)
                    {
                        return(EitherData.Right <L, Eff <B> >(FailEff <B>(ra.Error)));
                    }
                    var da = await ra.Value.Data.ConfigureAwait(false);

                    if (da.State == EitherStatus.IsBottom)
                    {
                        return(EitherData <L, Eff <B> > .Bottom);
                    }
                    if (da.State == EitherStatus.IsLeft)
                    {
                        return(EitherData.Left <L, Eff <B> >(da.Left));
                    }
                    return(EitherData.Right <L, Eff <B> >(SuccessEff <B>(f(da.Right))));
                }
            }
            catch (Exception e)
            {
                return(FailEff <B>(e));
            }
        }
Пример #13
0
 public static EitherUnsafe <L, Eff <A> > Sequence <L, A>(this Eff <EitherUnsafe <L, A> > ta) =>
 ta.Traverse(identity);
Пример #14
0
 public static Seq <Eff <A> > Sequence <A>(this Eff <Seq <A> > ta) =>
 ta.Traverse(identity);
Пример #15
0
 public static EitherAsync <L, Eff <B> > Sequence <L, A, B>(this Eff <A> ta, Func <A, EitherAsync <L, B> > f) =>
 ta.Map(f).Traverse(Prelude.identity);
Пример #16
0
 public static TryAsync <Eff <A> > Sequence <A>(this Eff <TryAsync <A> > ta) =>
 ta.Traverse(identity);
Пример #17
0
 /// <summary>
 /// Catch an error if the error matches the argument provided
 /// </summary>
 public static Eff <RT, A> Catch <RT, A>(this Eff <RT, A> ma, Error error, Eff <A> Fail) where RT : struct, HasCancel <RT> =>
 ma | matchError(e => e.Is(error), _ => Fail);
Пример #18
0
 /// <summary>
 /// Catch an error if the error matches the argument provided
 /// </summary>
 public static Eff <A> Catch <A>(this Eff <A> ma, Error error, Eff <A> Fail) =>
 ma | matchError(e => e.Is(error), _ => Fail);
Пример #19
0
 /// <summary>
 /// Catch an error if the error `Code` matches the `errorCode` argument provided
 /// </summary>
 public static Eff <RT, A> Catch <RT, A>(this Eff <RT, A> ma, int errorCode, Func <Error, Eff <A> > Fail) where RT : struct, HasCancel <RT> =>
 ma | matchError(e => e.Code == errorCode, Fail);
Пример #20
0
 /// <summary>
 /// Catch an error if the error `Code` matches the `errorCode` argument provided
 /// </summary>
 public static Eff <A> Catch <A>(this Eff <A> ma, int errorCode, Func <Error, Eff <A> > Fail) =>
 ma | matchError(e => e.Code == errorCode, Fail);
Пример #21
0
 public static TryAsync <Eff <B> > Sequence <A, B>(this Eff <A> ta, Func <A, TryAsync <B> > f) =>
 ta.Map(f).Traverse(Prelude.identity);
Пример #22
0
 public static Eff <RT, A> Repeat(Eff <RT, A> ma, Schedule schedule) =>
 schedule.Run(ma, static x => x.IsSucc);
Пример #23
0
 /// <summary>
 /// Catch all errors
 /// </summary>
 public static Eff <RT, A> Catch <RT, A>(this Eff <RT, A> ma, Eff <RT, A> Fail) where RT : struct, HasCancel <RT> =>
 ma | matchError(static _ => true, e => Fail);
Пример #24
0
 public static Eff <RT, Eff <A> > Sequence <RT, A>(this Eff <Eff <RT, A> > mma) where RT : struct =>
 mma.Traverse(identity);
Пример #25
0
 public static Validation <Fail, Eff <B> > Sequence <Fail, A, B>(this Eff <A> ta, Func <A, Validation <Fail, B> > f) =>
 ta.Map(f).Traverse(Prelude.identity);
Пример #26
0
 /// <summary>
 /// Catch an error if the error message matches the `errorText` argument provided
 /// </summary>
 public static Eff <RT, A> Catch <RT, A>(this Eff <RT, A> ma, string errorText, Eff <A> Fail) where RT : struct, HasCancel <RT> =>
 ma | matchError(e => e.Message == errorText, _ => Fail);
Пример #27
0
 public static Lst <Eff <B> > Traverse <A, B>(this Eff <Lst <A> > ma, Func <A, B> f) =>
 ma.Match(
     Fail: ex => List(FailEff <B>(ex)),
     Succ: xs => xs.Map(x => SuccessEff <B>(f(x)))).Run().Value;
Пример #28
0
 public static Lst <Eff <A> > Sequence <A>(this Eff <Lst <A> > ta) =>
 ta.Traverse(identity);
Пример #29
0
 public static Eff <RT, Eff <B> > Sequence <RT, A, B>(this Eff <A> ta, Func <A, Eff <RT, B> > f) where RT : struct =>
 ta.Map(f).Sequence();
Пример #30
0
 public static Aff <Eff <B> > Sequence <A, B>(this Eff <A> ta, Func <A, Aff <B> > f) =>
 ta.Map(f).Sequence();