public static MonadOr <TSource> PassBy <TSource, TOther>( this MonadOr <TSource> @this, MonadOr <TOther> other) { Require.NotNull(@this, nameof(@this)); return(@this.ZipWith(other, (arg, _) => arg)); }
public static MonadOr <TResult> ContinueWith <TSource, TResult>( this MonadOr <TSource> @this, MonadOr <TResult> other) { Require.NotNull(@this, nameof(@this)); return(@this.Bind(_ => other)); }
public static MonadOr <TResult> ReplaceBy <TSource, TResult>( this MonadOr <TSource> @this, TResult value) { Require.NotNull(@this, nameof(@this)); return(@this.Select(_ => value)); }
/// <seealso cref="Gather{TSource, TResult}" /> public static MonadOr <TResult> Apply <TSource, TResult>( this MonadOr <Func <TSource, TResult> > @this, MonadOr <TSource> value) { Require.NotNull(value, nameof(value)); return(value.Gather(@this)); }
/// <seealso cref="MonadOr.Lift{T1, T2, T3, T4, T5, TResult}"/> public static MonadOr <TResult> ZipWith <T1, T2, T3, T4, T5, TResult>( this MonadOr <T1> @this, MonadOr <T2> second, MonadOr <T3> third, MonadOr <T4> fourth, MonadOr <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)))); }
public static MonadOr <TResult> Select <TSource, TResult>( this MonadOr <TSource> @this, Func <TSource, TResult> selector) { Require.NotNull(@this, nameof(@this)); Require.NotNull(selector, nameof(selector)); return(@this.Bind(val => MonadOr <TResult> .η(selector(val)))); }
public static MonadOr <TSource> Where <TSource>( this MonadOr <TSource> @this, Func <TSource, bool> predicate) { Require.NotNull(@this, nameof(@this)); Require.NotNull(predicate, nameof(predicate)); return(@this.Bind(val => predicate(val) ? MonadOr <TSource> .η(val) : MonadOr <TSource> .None)); }
/// <seealso cref="Apply{TSource, TResult}(MonadOr{Func{TSource, TResult}}, MonadOr{TSource})" /> public static MonadOr <TResult> Gather <TSource, TResult>( this MonadOr <TSource> @this, MonadOr <Func <TSource, TResult> > applicative) { Require.NotNull(@this, nameof(@this)); Require.NotNull(applicative, nameof(applicative)); return(applicative.Bind(func => @this.Select(func))); }
// Bind() with automatic resource management. public static MonadOr <TResult> Using <TSource, TResult>( this MonadOr <TSource> @this, Func <TSource, MonadOr <TResult> > binder) where TSource : IDisposable { Require.NotNull(@this, nameof(@this)); Require.NotNull(binder, nameof(binder)); return(@this.Bind(val => { using (val) { return binder(val); } })); }
// Select() with automatic resource management. public static MonadOr <TResult> Using <TSource, TResult>( this MonadOr <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); } })); }
public static MonadOr <TResult> Join <TSource, TInner, TKey, TResult>( this MonadOr <TSource> @this, MonadOr <TInner> inner, Func <TSource, TKey> outerKeySelector, Func <TInner, TKey> innerKeySelector, Func <TSource, TInner, TResult> resultSelector) => @this.Join( inner, outerKeySelector, innerKeySelector, resultSelector, null);
private static Func <TKey, MonadOr <TInner> > GetKeyLookup <TInner, TKey>( MonadOr <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)); }
// Generalizes both Bind() and ZipWith<T1, T2, TResult>(). public static MonadOr <TResult> SelectMany <TSource, TMiddle, TResult>( this MonadOr <TSource> @this, Func <TSource, MonadOr <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)))); }
/// <seealso cref="MonadOr.Lift{T1, T2, TResult}"/> public static MonadOr <TResult> ZipWith <T1, T2, TResult>( this MonadOr <T1> @this, MonadOr <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)))); }
public static MonadOr <TResult> Join <TSource, TInner, TKey, TResult>( this MonadOr <TSource> @this, MonadOr <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, MonadOr <TInner> > valueSelector = outer => lookup(outerKeySelector(outer)); return(@this.SelectMany(valueSelector, resultSelector)); }
/// <seealso cref="MonadOr.Lift{T1, T2, T3, TResult}"/> public static MonadOr <TResult> ZipWith <T1, T2, T3, TResult>( this MonadOr <T1> @this, MonadOr <T2> second, MonadOr <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)))); }
public static MonadOr <unit> Skip <TSource>(this MonadOr <TSource> @this) { Require.NotNull(@this, nameof(@this)); return(@this.ContinueWith(MonadOr.Unit)); }
public MonadOr <T> OrElse(MonadOr <T> other) { throw new PrototypeException(); }
internal static MonadOr <T> μ(MonadOr <MonadOr <T> > square) => square.Bind(Stubs <MonadOr <T> > .Ident);
/// <summary> /// Removes one level of structure, projecting its bound value into the outer level. /// </summary> public static MonadOr <T> Flatten <T>(this MonadOr <MonadOr <T> > @this) => MonadOr <T> .μ(@this);