コード例 #1
0
ファイル: IAlternative.cs プロジェクト: nordril/functional
        /// <summary>
        /// Returns an <see cref="IAlternative{TSource}"/> containing <see cref="Maybe.Just{T}(T)"/> its value, if present, or <see cref="Maybe.Nothing{T}"/> otherwise.
        /// </summary>
        /// <typeparam name="TResult">The type of the value in <paramref name="alt"/>.</typeparam>
        /// <param name="alt">The <see cref="IAlternative{TSource}"/> to check.</param>
        public static IAlternative <Maybe <TResult> > Optional <TResult>(this IAlternative <TResult> alt)
        {
            var altM     = (IAlternative <Maybe <TResult> >)alt.Map(x => Maybe.Just(x));
            var nothingM = (IAlternative <Maybe <TResult> >)Applicative.PureUnsafe(Maybe.Nothing <TResult>(), altM.GetType());

            return(altM.Alt(nothingM));
        }
コード例 #2
0
ファイル: IFoldable.cs プロジェクト: nordril/functional
 /// <summary>
 /// A limited form of traversal which traverses a <see cref="IFoldable{TSource}"/> structure and discards the results.
 /// </summary>
 /// <typeparam name="TSource">The type of the element in the input structure.</typeparam>
 /// <typeparam name="TResult">The type of the result of the action.</typeparam>
 /// <param name="applicative">The type of the applicative.</param>
 /// <param name="foldable">The object to fold.</param>
 /// <param name="f">The function to apply to each contained element.</param>
 public static IApplicative <Unit> TraverseDiscard <TSource, TResult>(
     this IFoldable <TSource> foldable,
     Type applicative,
     Func <TSource, IApplicative <TResult> > f)
 {
     return(foldable.Foldr(
                (x, acc) => f(x).ApRight(acc),
                Applicative.PureUnsafe(new Unit(), applicative)));
 }
コード例 #3
0
        /// <summary>
        /// An asynchronous monadic <see cref="CollectionExtensions.Unfold{TSeed, TResult}(TSeed, Func{TSeed, Maybe{ValueTuple{TSeed, TResult}}})"/> which generates a sequence each time the <paramref name="seed"/>-value evaluates to <see cref="Maybe.Just{T}(T)"/>.<br />
        /// Equivalent to:
        /// <code>
        /// while ((await seed()).TryGetValue(_, y)) { yield return y; }
        /// </code>
        /// </summary>
        /// <typeparam name="TSource">The type of the seed/generated elements.</typeparam>
        /// <param name="seed">The monadic seed-value.</param>
        /// <param name="token">The cancellation token.</param>
        public static Task <IAsyncMonad <IEnumerable <TSource> > > UnfoldMAsync <TSource>(
            this Task <IAsyncMonad <Maybe <TSource> > > seed,
            CancellationToken token = default)
        {
            Task <IAsyncMonad <IEnumerable <TSource> > > go()
            {
                if (token.IsCancellationRequested)
                {
                    return(Task.FromResult(Applicative.PureUnsafe((IEnumerable <TSource>)Array.Empty <TSource>(), seed.GetType()).ToAsyncMonad()));
                }

                var q = seed.BindAsync((Maybe <TSource> x) =>
                                       x.TryGetValue(default, out var y)
コード例 #4
0
        /// <summary>
        /// Runs <paramref name="condition"/> repeatedly as long as it returns <c>true</c>, and runs <paramref name="body"/> each time, collecting the results.<br />
        /// Equivalent to:
        /// <code>
        /// while (await condition())
        /// {
        ///     yield return await body();
        /// }
        /// </code>
        /// </summary>
        /// <typeparam name="TSource">The type of the seed/generated elements.</typeparam>
        /// <param name="condition">The asynchronous monadic function which computes the condition.</param>
        /// <param name="body">The monadic body.</param>
        /// <param name="token">The cancellation token.</param>
        public static Task <IAsyncMonad <IEnumerable <TSource> > > WhileMAsync <TSource>(
            this Task <IAsyncMonad <bool> > condition,
            Func <Task <IAsyncMonad <TSource> > > body,
            CancellationToken token = default)
        {
            Type conditionType = null;

            Task <IAsyncMonad <IEnumerable <TSource> > > go()
            {
                if (token.IsCancellationRequested && conditionType is not null)
                {
                    return(Task.FromResult(
                               Applicative.PureUnsafe((IEnumerable <TSource>)Array.Empty <TSource>(), conditionType)
                               .ToAsyncMonad()));
                }

                var q = condition.BindAsync((Type t, bool conditionResult) =>
                {
                    conditionType ??= t;
                    return(conditionResult
                        ? (body().BindAsync((TSource bodyResult) =>
                                            go().MapAsync((IEnumerable <TSource> rest) =>
                                                          Task.FromResult(rest.Prepend(bodyResult)), token), token))
                        : Task.FromResult(Applicative.PureUnsafe((IEnumerable <TSource>)Array.Empty <TSource>(), t).ToAsyncMonad()));
                }, token);

                /*var q =
                 *  from conditionResult in condition
                 *  from results in conditionResult
                 *      ? from bodyResult in body()
                 *        from rest in go()
                 *        select rest.Prepend(bodyResult)
                 *      : Task.FromResult((IAsyncMonad<IEnumerable<TSource>>)Applicative.PureUnsafe((IEnumerable<TSource>)Array.Empty<TSource>(), condition.GetType()))
                 *  select results;*/

                return(q);
            }

            return(go());
        }