Ejemplo n.º 1
0
        /// <seealso cref="MonadPlus.Lift{T1, T2, T3, T4, T5, TResult}"/>
        public static MonadPlus <TResult> ZipWith <T1, T2, T3, T4, T5, TResult>(
            this MonadPlus <T1> @this,
            MonadPlus <T2> second,
            MonadPlus <T3> third,
            MonadPlus <T4> fourth,
            MonadPlus <T5> fifth,
            Func <T1, T2, T3, T4, T5, TResult> zipper)
        {
            Require.NotNull(@this, nameof(@this));
            Require.NotNull(second, nameof(second));
            Require.NotNull(third, nameof(third));
            Require.NotNull(fourth, nameof(fourth));
            Require.NotNull(fifth, nameof(fifth));
            Require.NotNull(zipper, nameof(zipper));

            // > return @this.Bind(
            // >     arg1 => second.Bind(
            // >         arg2 => third.Bind(
            // >             arg3 => fourth.Bind(
            // >                 arg4 => fifth.Select(
            // >                     arg5 => zipper(arg1, arg2, arg3, arg4, arg5))))));
            return(@this.Bind(
                       arg1 => second.ZipWith(
                           third,
                           fourth,
                           fifth,
                           (arg2, arg3, arg4, arg5) => zipper(arg1, arg2, arg3, arg4, arg5))));
        }
Ejemplo n.º 2
0
 public static MonadPlus <TSource> PassBy <TSource, TOther>(
     this MonadPlus <TSource> @this,
     MonadPlus <TOther> other)
 {
     Require.NotNull(@this, nameof(@this));
     return(@this.ZipWith(other, (arg, _) => arg));
 }
Ejemplo n.º 3
0
 public static MonadPlus <TResult> ReplaceBy <TSource, TResult>(
     this MonadPlus <TSource> @this,
     TResult value)
 {
     Require.NotNull(@this, nameof(@this));
     return(@this.Select(_ => value));
 }
Ejemplo n.º 4
0
 public static MonadPlus <TResult> ContinueWith <TSource, TResult>(
     this MonadPlus <TSource> @this,
     MonadPlus <TResult> other)
 {
     Require.NotNull(@this, nameof(@this));
     return(@this.Bind(_ => other));
 }
Ejemplo n.º 5
0
 /// <seealso cref="Gather{TSource, TResult}" />
 public static MonadPlus <TResult> Apply <TSource, TResult>(
     this MonadPlus <Func <TSource, TResult> > @this,
     MonadPlus <TSource> value)
 {
     Require.NotNull(value, nameof(value));
     return(value.Gather(@this));
 }
Ejemplo n.º 6
0
 public static MonadPlus <TResult> Select <TSource, TResult>(
     this MonadPlus <TSource> @this,
     Func <TSource, TResult> selector)
 {
     Require.NotNull(@this, nameof(@this));
     Require.NotNull(selector, nameof(selector));
     return(@this.Bind(val => MonadPlus <TResult> .η(selector(val))));
 }
Ejemplo n.º 7
0
 /// <seealso cref="Apply{TSource, TResult}(MonadPlus{Func{TSource, TResult}}, MonadPlus{TSource})" />
 public static MonadPlus <TResult> Gather <TSource, TResult>(
     this MonadPlus <TSource> @this,
     MonadPlus <Func <TSource, TResult> > applicative)
 {
     Require.NotNull(@this, nameof(@this));
     Require.NotNull(applicative, nameof(applicative));
     return(applicative.Bind(func => @this.Select(func)));
 }
Ejemplo n.º 8
0
 public static MonadPlus <TSource> Where <TSource>(
     this MonadPlus <TSource> @this,
     Func <TSource, bool> predicate)
 {
     Require.NotNull(@this, nameof(@this));
     Require.NotNull(predicate, nameof(predicate));
     return(@this.Bind(val => predicate(val) ? MonadPlus <TSource> .η(val) : MonadPlus <TSource> .Zero));
 }
Ejemplo n.º 9
0
 // Select() with automatic resource management.
 public static MonadPlus <TResult> Using <TSource, TResult>(
     this MonadPlus <TSource> @this,
     Func <TSource, TResult> selector)
     where TSource : IDisposable
 {
     Require.NotNull(@this, nameof(@this));
     Require.NotNull(selector, nameof(selector));
     return(@this.Select(val => { using (val) { return selector(val); } }));
 }
Ejemplo n.º 10
0
 // Bind() with automatic resource management.
 public static MonadPlus <TResult> Using <TSource, TResult>(
     this MonadPlus <TSource> @this,
     Func <TSource, MonadPlus <TResult> > binder)
     where TSource : IDisposable
 {
     Require.NotNull(@this, nameof(@this));
     Require.NotNull(binder, nameof(binder));
     return(@this.Bind(val => { using (val) { return binder(val); } }));
 }
Ejemplo n.º 11
0
 public static MonadPlus <TResult> Join <TSource, TInner, TKey, TResult>(
     this MonadPlus <TSource> @this,
     MonadPlus <TInner> inner,
     Func <TSource, TKey> outerKeySelector,
     Func <TInner, TKey> innerKeySelector,
     Func <TSource, TInner, TResult> resultSelector)
 => @this.Join(
     inner,
     outerKeySelector,
     innerKeySelector,
     resultSelector,
     null);
Ejemplo n.º 12
0
        // Generalizes both Bind() and ZipWith<T1, T2, TResult>().
        public static MonadPlus <TResult> SelectMany <TSource, TMiddle, TResult>(
            this MonadPlus <TSource> @this,
            Func <TSource, MonadPlus <TMiddle> > selector,
            Func <TSource, TMiddle, TResult> resultSelector)
        {
            Require.NotNull(@this, nameof(@this));
            Require.NotNull(selector, nameof(selector));
            Require.NotNull(resultSelector, nameof(resultSelector));

            return(@this.Bind(
                       val => selector(val).Select(
                           middle => resultSelector(val, middle))));
        }
Ejemplo n.º 13
0
        /// <seealso cref="MonadPlus.Lift{T1, T2, TResult}"/>
        public static MonadPlus <TResult> ZipWith <T1, T2, TResult>(
            this MonadPlus <T1> @this,
            MonadPlus <T2> second,
            Func <T1, T2, TResult> zipper)
        {
            Require.NotNull(@this, nameof(@this));
            Require.NotNull(second, nameof(second));
            Require.NotNull(zipper, nameof(zipper));

            return(@this.Bind(
                       arg1 => second.Select(
                           arg2 => zipper(arg1, arg2))));
        }
Ejemplo n.º 14
0
        private static Func <TKey, MonadPlus <TInner> > GetKeyLookup <TInner, TKey>(
            MonadPlus <TInner> inner,
            Func <TInner, TKey> innerKeySelector,
            IEqualityComparer <TKey> comparer)
        {
            Debug.Assert(inner != null);
            Debug.Assert(innerKeySelector != null);

            return(outerKey =>
                   inner.Select(innerKeySelector)
                   .Where(innerKey => (comparer ?? EqualityComparer <TKey> .Default).Equals(innerKey, outerKey))
                   .ContinueWith(inner));
        }
Ejemplo n.º 15
0
        public static MonadPlus <TResult> Join <TSource, TInner, TKey, TResult>(
            this MonadPlus <TSource> @this,
            MonadPlus <TInner> inner,
            Func <TSource, TKey> outerKeySelector,
            Func <TInner, TKey> innerKeySelector,
            Func <TSource, TInner, TResult> resultSelector,
            IEqualityComparer <TKey> comparer)
        {
            Require.NotNull(@this, nameof(@this));
            Require.NotNull(inner, nameof(inner));
            Require.NotNull(resultSelector, nameof(resultSelector));
            Require.NotNull(outerKeySelector, nameof(outerKeySelector));
            Require.NotNull(innerKeySelector, nameof(innerKeySelector));

            var lookup = GetKeyLookup(inner, innerKeySelector, comparer);
            Func <TSource, MonadPlus <TInner> > valueSelector = outer => lookup(outerKeySelector(outer));

            return(@this.SelectMany(valueSelector, resultSelector));
        }
Ejemplo n.º 16
0
        /// <seealso cref="MonadPlus.Lift{T1, T2, T3, TResult}"/>
        public static MonadPlus <TResult> ZipWith <T1, T2, T3, TResult>(
            this MonadPlus <T1> @this,
            MonadPlus <T2> second,
            MonadPlus <T3> third,
            Func <T1, T2, T3, TResult> zipper)
        {
            Require.NotNull(@this, nameof(@this));
            Require.NotNull(second, nameof(second));
            Require.NotNull(third, nameof(third));
            Require.NotNull(zipper, nameof(zipper));

            // This is the same as:
            // > return @this.Bind(
            // >     arg1 => second.Bind(
            // >        arg2 => third.Select(
            // >            arg3 => zipper(arg1, arg2, arg3))));
            // but faster if ZipWith is locally shadowed.
            return(@this.Bind(
                       arg1 => second.ZipWith(
                           third, (arg2, arg3) => zipper(arg1, arg2, arg3))));
        }
Ejemplo n.º 17
0
 public MonadPlus <T> Plus(MonadPlus <T> other)
 {
     throw new PrototypeException();
 }
Ejemplo n.º 18
0
 public static MonadPlus <unit> Skip <TSource>(this MonadPlus <TSource> @this)
 {
     Require.NotNull(@this, nameof(@this));
     return(@this.ContinueWith(MonadPlus.Unit));
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Removes one level of structure, projecting its bound value into the outer level.
 /// </summary>
 public static MonadPlus <T> Flatten <T>(this MonadPlus <MonadPlus <T> > @this)
 => MonadPlus <T> .μ(@this);
Ejemplo n.º 20
0
 internal static MonadPlus <T> μ(MonadPlus <MonadPlus <T> > square)
 => square.Bind(Stubs <MonadPlus <T> > .Ident);