public TryOptionAsync <B> Apply(TryOptionAsync <Func <A, B> > fab, TryOptionAsync <A> fa) =>
        async() =>
        {
            var f = fab.Try();
            var a = fa.Try();

            await Task.WhenAll(f, a);

            var rf = await f;
            if (rf.IsFaulted)
            {
                return(new OptionalResult <B>(rf.Exception));
            }
            if (rf.IsFaultedOrNone)
            {
                return(OptionalResult <B> .None);
            }

            var ra = await a;
            if (ra.IsFaulted)
            {
                return(new OptionalResult <B>(ra.Exception));
            }
            if (ra.IsFaultedOrNone)
            {
                return(OptionalResult <B> .None);
            }

            return(new OptionalResult <B>(rf.Value.Value(ra.Value.Value)));
        };
Example #2
0
        public static TryAsync <TryOptionAsync <B> > Traverse <A, B>(this TryOptionAsync <TryAsync <A> > ma, Func <A, B> f)
        {
            return(ToTry(() => Go(ma, f)));

            async Task <Result <TryOptionAsync <B> > > Go(TryOptionAsync <TryAsync <A> > ma, Func <A, B> f)
            {
                var ra = await ma.Try().ConfigureAwait(false);

                if (ra.IsFaulted)
                {
                    return(new Result <TryOptionAsync <B> >(TryOptionAsync <B>(ra.Exception)));
                }
                if (ra.IsNone)
                {
                    return(new Result <TryOptionAsync <B> >(TryOptionAsync <B>(None)));
                }
                var rb = await ra.Value.Value.Try().ConfigureAwait(false);

                if (rb.IsFaulted)
                {
                    return(new Result <TryOptionAsync <B> >(rb.Exception));
                }
                return(new Result <TryOptionAsync <B> >(TryOptionAsync <B>(f(rb.Value))));
            }
        }
        public TryOptionAsync <B> Action(TryOptionAsync <A> fa, TryOptionAsync <B> fb) =>
        async() =>
        {
            var a = fa.Try();
            var b = fb.Try();

            await Task.WhenAll(a, b);

            var ra = await a;
            if (ra.IsFaulted)
            {
                return(new OptionalResult <B>(ra.Exception));
            }
            if (ra.IsFaultedOrNone)
            {
                return(OptionalResult <B> .None);
            }

            var rb = await b;
            if (rb.IsFaulted)
            {
                return(new OptionalResult <B>(rb.Exception));
            }
            if (rb.IsFaultedOrNone)
            {
                return(OptionalResult <B> .None);
            }

            return(new OptionalResult <B>(rb.Value));
        };
        public static EitherAsync <L, TryOptionAsync <B> > Traverse <L, A, B>(this TryOptionAsync <EitherAsync <L, A> > ma, Func <A, B> f)
        {
            return(new EitherAsync <L, TryOptionAsync <B> >(Go(ma, f)));

            async Task <EitherData <L, TryOptionAsync <B> > > Go(TryOptionAsync <EitherAsync <L, A> > ma, Func <A, B> f)
            {
                var result = await ma.Try().ConfigureAwait(false);

                if (result.IsBottom)
                {
                    return(EitherData <L, TryOptionAsync <B> > .Bottom);
                }
                if (result.IsFaulted)
                {
                    return(EitherData.Right <L, TryOptionAsync <B> >(TryOptionAsyncFail <B>(result.Exception)));
                }
                if (result.IsNone)
                {
                    return(EitherData.Right <L, TryOptionAsync <B> >(TryOptionAsync <B>(None)));
                }
                var db = await result.Value.Value.Data.ConfigureAwait(false);

                if (db.State == EitherStatus.IsBottom)
                {
                    return(EitherData <L, TryOptionAsync <B> > .Bottom);
                }
                if (db.State == EitherStatus.IsLeft)
                {
                    return(EitherData.Left <L, TryOptionAsync <B> >(db.Left));
                }
                return(EitherData.Right <L, TryOptionAsync <B> >(TryOptionAsync <B>(f(db.Right))));
            }
        }
        public async Task <bool> EqualsAsync(TryOptionAsync <A> x, TryOptionAsync <A> y)
        {
            var dx = await x.Try().ConfigureAwait(false);

            var dy = await y.Try().ConfigureAwait(false);

            if (dx.IsBottom && dy.IsBottom)
            {
                return(true);
            }
            if (dx.IsFaulted && dy.IsFaulted)
            {
                return(true);
            }
            if (dx.IsNone && dy.IsNone)
            {
                return(true);
            }
            if (dx.IsSome && dy.IsSome)
            {
                return(await default(EqA).EqualsAsync(dx.Value.Value, dy.Value.Value).ConfigureAwait(false));
            }
            else
            {
                return(false);
            }
        }
Example #6
0
        public async Task <int> CompareAsync(TryOptionAsync <A> x, TryOptionAsync <A> y)
        {
            var dx = await x.Try().ConfigureAwait(false);

            var dy = await y.Try().ConfigureAwait(false);

            if (dx.IsBottom && dy.IsBottom)
            {
                return(0);
            }
            if (dx.IsFaulted && dy.IsFaulted)
            {
                return(0);
            }
            if (dx.IsNone && dy.IsNone)
            {
                return(0);
            }
            if (dx.IsSome && dy.IsSome)
            {
                return(await default(OrdA).CompareAsync(dx.Value.Value, dy.Value.Value).ConfigureAwait(false));
            }

            if (dx.IsBottom && !dy.IsBottom)
            {
                return(-1);
            }
            if (!dx.IsBottom && dy.IsBottom)
            {
                return(1);
            }

            if (dx.IsFaulted && !dy.IsFaulted)
            {
                return(-1);
            }
            if (!dx.IsFaulted && dy.IsFaulted)
            {
                return(1);
            }

            if (dx.IsNone && !dy.IsNone)
            {
                return(-1);
            }
            if (!dx.IsNone && dy.IsNone)
            {
                return(1);
            }

            if (dx.IsSome && !dy.IsSome)
            {
                return(-1);
            }
            if (!dx.IsSome && dy.IsSome)
            {
                return(1);
            }
            return(0);
        }
 public MB BindAsync <MONADB, MB, B>(TryOptionAsync <A> ma, Func <A, Task <MB> > f) where MONADB : struct, MonadAsync <Unit, Unit, MB, B> =>
 default(MONADB).RunAsync(async _ =>
 {
     try
     {
         var ra = await ma.Try();
         if (ra.IsBottom)
         {
             return(default(MONADB).Fail(new TaskCanceledException()));
         }
         if (ra.IsFaulted)
         {
             return(default(MONADB).Fail(ra.Exception));
         }
         if (ra.IsFaultedOrNone)
         {
             return(default(MONADB).Zero());
         }
         return(await f(ra.Value.Value));
     }
     catch (Exception e)
     {
         return(default(MONADB).Fail(e));
     }
 });
        public TryOptionAsync <B> Apply(Func <A, A, B> fab, TryOptionAsync <A> fa, TryOptionAsync <A> fb) =>
        async() =>
        {
            var a = fa.Try();
            var b = fb.Try();

            await Task.WhenAll(a, b).ConfigureAwait(false);

            var ra = await a.ConfigureAwait(false);

            if (ra.IsFaulted)
            {
                return(new OptionalResult <B>(ra.Exception));
            }
            if (ra.IsFaultedOrNone)
            {
                return(OptionalResult <B> .None);
            }

            var rb = await b.ConfigureAwait(false);

            if (rb.IsFaulted)
            {
                return(new OptionalResult <B>(rb.Exception));
            }
            if (rb.IsFaultedOrNone)
            {
                return(OptionalResult <B> .None);
            }

            return(new OptionalResult <B>(fab(ra.Value.Value, rb.Value.Value)));
        };
        public TryOptionAsync <A> Plus(TryOptionAsync <A> ma, TryOptionAsync <A> mb) => async() =>
        {
            // Run in parallel
            var resA = ma.Try();
            var resB = mb.Try();

            var tasks = Set <OrdTask <OptionalResult <A> >, Task <OptionalResult <A> > >(resA, resB);

            while (tasks.Count > 0)
            {
                // Return first one that completes
                var completed = await Task.WhenAny(tasks);

                if (!completed.IsFaulted && !completed.Result.IsFaulted)
                {
                    return(completed.Result);
                }
                tasks = tasks.Remove(completed);
            }
            if (!resA.IsFaulted)
            {
                return(resA.Result);
            }
            if (!resB.IsFaulted)
            {
                return(resB.Result);
            }
            return(OptionalResult <A> .None);
        };
Example #10
0
        public async Task <int> GetHashCodeAsync(TryOptionAsync <A> x)
        {
            var dx = await x.Try();

            return(dx.IsSome
                ? await default(HashA).GetHashCodeAsync(dx.Value.Value)
                : 0);
        }
Example #11
0
        /// <summary>
        /// Performs the given action if the operation results in a failed state
        /// </summary>
        /// <param name="t">Current operation</param>
        /// <param name="ifFail">Action to execute with the exception that caused the failure</param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static TryOptionAsync <T> DoIfFail <T>(this TryOptionAsync <T> t, Action <Exception> ifFail) => async() =>
        {
            var optionResult = await t.Try();

            if (optionResult.IsFaulted)
            {
                optionResult.IfFail(ifFail);
            }

            return(optionResult);
        };
        public TryOptionAsync <A> Apply(Func <A, A, A> f, TryOptionAsync <A> fa, TryOptionAsync <A> fb) => async() =>
        {
            // Run in parallel
            var resA      = fa.Try();
            var resB      = fb.Try();
            var completed = await Task.WhenAll(resA, resB);

            return(!completed[0].IsFaulted && !completed[1].IsFaulted && completed[0].Value.IsSome && completed[1].Value.IsSome
                ? Option <A> .Some(f(completed[0].Value.Value, completed[1].Value.Value))
                : Option <A> .None); // TODO: Propagate exceptions
        };
        public TryOptionAsync <A> Plus(TryOptionAsync <A> ma, TryOptionAsync <A> mb) => async() =>
        {
            var a = await ma.Try().ConfigureAwait(false);

            if (!a.IsFaultedOrNone)
            {
                return(a);
            }
            var b = await mb.Try().ConfigureAwait(false);

            return(b.IsFaulted && a.IsFaulted
                ? new OptionalResult <A>(new AggregateException(a.Exception, b.Exception))
                : b);
        };
        public TryOptionAsync <B> Apply(Func <A, B> fab, TryOptionAsync <A> fa) =>
        async() =>
        {
            var a = fa.Try();

            var ra = await a;
            if (ra.IsFaulted)
            {
                return(new OptionalResult <B>(ra.Exception));
            }
            if (ra.IsFaultedOrNone)
            {
                return(OptionalResult <B> .None);
            }

            return(new OptionalResult <B>(fab(ra.Value.Value)));
        };
Example #15
0
        public static async Task <TryOptionAsync <B> > Traverse <A, B>(this TryOptionAsync <Task <A> > ma, Func <A, B> f)
        {
            var da = await ma.Try().ConfigureAwait(false);

            if (da.IsBottom)
            {
                throw new BottomException();
            }
            if (da.IsNone)
            {
                return(TryOptionalAsync <B>(None));
            }
            if (da.IsFaulted)
            {
                return(TryOptionAsyncFail <B>(da.Exception));
            }
            #nullable disable
Example #16
0
        public TryOptionAsync <B> Apply(TryOptionAsync <Func <A, B> > fab, TryOptionAsync <A> fa) =>
        async() =>
        {
            var f = fab.Try();
            var a = fa.Try();

            await Task.WhenAll(f, a);

            if (f.IsFaulted || f.Result.IsFaultedOrNone)
            {
                return(new OptionalResult <B>(f.Exception));
            }
            if (a.IsFaulted || a.Result.IsFaultedOrNone)
            {
                return(new OptionalResult <B>(a.Exception));
            }

            return(new OptionalResult <B>(f.Result.Value.Value(a.Result.Value.Value)));
        };
Example #17
0
        public TryOptionAsync <B> Action(TryOptionAsync <A> fa, TryOptionAsync <B> fb) =>
        async() =>
        {
            var a = fa.Try();
            var b = fb.Try();

            await Task.WhenAll(a, b);

            if (a.IsFaulted || a.Result.IsFaultedOrNone)
            {
                return(new OptionalResult <B>(a.Exception));
            }
            if (b.IsFaulted || b.Result.IsFaultedOrNone)
            {
                return(new OptionalResult <B>(b.Exception));
            }

            return(new OptionalResult <B>(b.Result.Value));
        };
Example #18
0
 public B Match <B>(TryOptionAsync <A> opt, Func <A, B> Some, Func <B> None)
 {
     try
     {
         var res = opt.Try().Result; // TODO: No asynchrony
         if (res.IsFaultedOrNone)
         {
             return(None());
         }
         else
         {
             return(Some(res.Value.Value));
         }
     }
     catch
     {
         return(None());
     }
 }
Example #19
0
        public static async ValueTask <TryOptionAsync <B> > Traverse <A, B>(this TryOptionAsync <ValueTask <A> > ma, Func <A, B> f)
        {
            var da = await ma.Try().ConfigureAwait(false);

            if (da.IsBottom)
            {
                throw new BottomException();
            }
            if (da.IsNone)
            {
                return(TryOptionalAsync <B>(None));
            }
            if (da.IsFaulted)
            {
                return(TryOptionAsyncFail <B>(da.Exception));
            }
            var a = await da.Value.Value.ConfigureAwait(false);

            return(TryOptionAsyncSucc(f(a)));
        }
Example #20
0
 public MB Bind <MONADB, MB, B>(TryOptionAsync <A> ma, Func <A, MB> f) where MONADB : struct, Monad <Unit, Unit, MB, B> =>
 default(MONADB).IdAsync(_ => ma.Try().ContinueWith(task =>
 {
     try
     {
         return(task.IsFaulted
                 ? default(MONADB).Fail(task.Exception)
                 : task.IsCanceled
                     ? default(MONADB).Fail(new TaskCanceledException())
                     : task.Result.IsFaulted
                         ? default(MONADB).Fail(task.Result.Exception)
                         : task.Result.Value.IsNone || task.Result.IsBottom
                             ? default(MONADB).Fail(new TaskCanceledException())
                             : f(task.Result.Value.Value));
     }
     catch (Exception e)
     {
         return(default(MONADB).Fail(e));
     }
 }));
        public TryOptionAsync <B> ApplyOption(Func <Option <A>, Option <A>, B> fab, TryOptionAsync <A> fa, TryOptionAsync <A> fb) =>
        async() =>
        {
            var a = fa.Try();
            var b = fb.Try();

            await Task.WhenAll(a, b);

            var ra = await a;
            if (ra.IsFaulted)
            {
                return(new OptionalResult <B>(ra.Exception));
            }

            var rb = await b;
            if (rb.IsFaulted)
            {
                return(new OptionalResult <B>(rb.Exception));
            }

            return(new OptionalResult <B>(fab(ra.Value, rb.Value)));
        };
Example #22
0
        public static async Task <TryOptionAsync <B> > Traverse <A, B>(this TryOptionAsync <Task <A> > ma, Func <A, B> f)
        {
            var da = await ma.Try();

            if (da.IsBottom)
            {
                throw new BottomException();
            }
            if (da.IsNone)
            {
                return(TryOptionalAsync <B>(None));
            }
            if (da.IsFaulted)
            {
                return(TryOptionAsyncFail <B>(da.Exception));
            }
            var a = await da.Value.Value;

            if (da.Value.Value.IsFaulted)
            {
                ExceptionDispatchInfo.Capture(da.Value.Value.Exception.InnerException).Throw();
            }
            return(TryOptionAsyncSucc(f(a)));
        }
Example #23
0
 /// <summary>
 /// Turns the computation into an observable stream
 /// </summary>
 /// <typeparam name="A">Bound type</typeparam>
 /// <typeparam name="B">Returned observable bound type</typeparam>
 /// <param name="ma">This</param>
 /// <param name="Some">Function to call when the operation succeeds</param>
 /// <param name="None">Function to call when the operation succeeds but returns no value</param>
 /// <param name="Fail">Function to call when the operation fails</param>
 /// <returns>An observable that represents the result of Succ or Fail</returns>
 public static IObservable <B> MatchObservable <A, B>(this TryOptionAsync <A> ma, Func <A, IObservable <B> > Some, Func <IObservable <B> > None, Func <Exception, B> Fail) =>
 from ra in ma.Try().ToObservable()
 from rb in ra.Match(Some, None, e => Observable.Return(Fail(e)))
 select rb;
 public static TryOptionAsync <bool> isFail <T>(TryOptionAsync <T> self) => async() =>
 (await self.Try().ConfigureAwait(false)).IsFaultedOrNone;
Example #25
0
 public static IObservable <A> ToObservable <A>(this TryOptionAsync <A> ma) =>
 from ra in ma.Try().ToObservable()
     where ra.IsSome
 select ra.IfFailOrNone(default(A));
Example #26
0
 /// <summary>
 /// Turns the computation into an observable stream
 /// </summary>
 /// <typeparam name="A">Bound type</typeparam>
 /// <typeparam name="R">Returned observable bound type</typeparam>
 /// <param name="ma">This</param>
 /// <param name="Some">Function to call when the operation succeeds</param>
 /// <param name="None">Function to call when the operation succeeds but returns no value</param>
 /// <param name="Fail">Function to call when the operation fails</param>
 /// <returns>An observable that represents the result of Succ or Fail</returns>
 public static IObservable <R> MatchObservable <A, R>(this TryOptionAsync <A> ma, Func <A, R> Some, Func <IObservable <R> > None, Func <Exception, IObservable <R> > Fail) =>
 from ra in ma.Try().ToObservable()
 from rb in ra.Match(x => Observable.Return(Some(x)), None, Fail)
 select rb;
Example #27
0
 public static TryOptionAsync <bool> isFail <T>(TryOptionAsync <T> self) => async() =>
 (await self.Try()).IsFaultedOrNone;