Skip to content

Commit

Permalink
Add Prelude functions for Arithmetic typeclass
Browse files Browse the repository at this point in the history
  • Loading branch information
benjstephenson committed Mar 15, 2023
1 parent 4371712 commit ef270f5
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 137 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ IEnumerable<A> ToSequence(Seq<Option<A>> items)
/// <returns>An option with y added to x</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Option<A> Add<NUM, A>(this Option<A> x, Option<A> y) where NUM : struct, Num<A> =>
public static Option<A> Add<ARITH, A>(this Option<A> x, Option<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select plus<NUM, A>(a, b);
select plus<ARITH, A>(a, b);

/// <summary>
/// Find the subtract between the two bound values of x and y, uses a Subtract type-class
/// Find the subtract between the two bound values of x and y, uses a Subtract type-class
/// to provide the subtract operation for type A. For example x.Subtract<TInteger,int>(y)
/// </summary>
/// <typeparam name="DIFF">Subtract of A</typeparam>
Expand All @@ -91,13 +91,13 @@ from b in y
/// <returns>An option with the subtract between x and y</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Option<A> Subtract<NUM, A>(this Option<A> x, Option<A> y) where NUM : struct, Num<A> =>
public static Option<A> Subtract<ARITH, A>(this Option<A> x, Option<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select subtract<NUM, A>(a, b);
select subtract<ARITH, A>(a, b);

/// <summary>
/// Find the product between the two bound values of x and y, uses a Product type-class
/// Find the product between the two bound values of x and y, uses a Product type-class
/// to provide the product operation for type A. For example x.Product<TInteger,int>(y)
/// </summary>
/// <typeparam name="PROD">Product of A</typeparam>
Expand All @@ -107,10 +107,10 @@ from b in y
/// <returns>An option with the product of x and y</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Option<A> Product<NUM, A>(this Option<A> x, Option<A> y) where NUM : struct, Num<A> =>
public static Option<A> Product<ARITH, A>(this Option<A> x, Option<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select product<NUM, A>(a, b);
select product<ARITH, A>(a, b);

/// <summary>
/// Divide the two bound values of x and y, uses a Divide type-class to provide the divide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static async Task<IEnumerable<A>> Somes<A>(this IEnumerable<OptionAsync<A
.ConfigureAwait(false);
return res.Filter(x => x.IsSome).Map(x => x.Value).ToArray();
}


/// <summary>
/// Extracts from a list of `OptionAsync` all the `Some` elements.
Expand All @@ -47,7 +47,7 @@ public static async Task<Seq<A>> Somes<A>(this Seq<OptionAsync<A>> self)
.WindowMap(identity)
.ConfigureAwait(false);
return res.Filter(x => x.IsSome).Map(x => x.Value).ToSeq();
}
}

/// <summary>
/// Add the bound values of x and y, uses an Add type-class to provide the add
Expand All @@ -59,13 +59,13 @@ public static async Task<Seq<A>> Somes<A>(this Seq<OptionAsync<A>> self)
/// <param name="y">Right hand side of the operation</param>
/// <returns>An option with y added to x</returns>
[Pure]
public static OptionAsync<A> Add<NUM, A>(this OptionAsync<A> x, OptionAsync<A> y) where NUM : struct, Num<A> =>
public static OptionAsync<A> Add<ARITH, A>(this OptionAsync<A> x, OptionAsync<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select plus<NUM, A>(a, b);
select plus<ARITH, A>(a, b);

/// <summary>
/// Find the subtract between the two bound values of x and y, uses a Subtract type-class
/// Find the subtract between the two bound values of x and y, uses a Subtract type-class
/// to provide the subtract operation for type A. For example x.Subtract<TInteger,int>(y)
/// </summary>
/// <typeparam name="DIFF">Subtract of A</typeparam>
Expand All @@ -74,13 +74,13 @@ from b in y
/// <param name="y">Right hand side of the operation</param>
/// <returns>An option with the subtract between x and y</returns>
[Pure]
public static OptionAsync<A> Subtract<NUM, A>(this OptionAsync<A> x, OptionAsync<A> y) where NUM : struct, Num<A> =>
public static OptionAsync<A> Subtract<ARITH, A>(this OptionAsync<A> x, OptionAsync<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select subtract<NUM, A>(a, b);
select subtract<ARITH, A>(a, b);

/// <summary>
/// Find the product between the two bound values of x and y, uses a Product type-class
/// Find the product between the two bound values of x and y, uses a Product type-class
/// to provide the product operation for type A. For example x.Product<TInteger,int>(y)
/// </summary>
/// <typeparam name="PROD">Product of A</typeparam>
Expand All @@ -89,10 +89,10 @@ from b in y
/// <param name="y">Right hand side of the operation</param>
/// <returns>An option with the product of x and y</returns>
[Pure]
public static OptionAsync<A> Product<NUM, A>(this OptionAsync<A> x, OptionAsync<A> y) where NUM : struct, Num<A> =>
public static OptionAsync<A> Product<ARITH, A>(this OptionAsync<A> x, OptionAsync<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select product<NUM, A>(a, b);
select product<ARITH, A>(a, b);

/// <summary>
/// Divide the two bound values of x and y, uses a Divide type-class to provide the divide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static IEnumerable<A> Somes<A>(this IEnumerable<OptionUnsafe<A>> self)
}
}
}

/// <summary>
/// Extracts from a list of `OptionUnsafe` all the `Some` elements.
/// All the `Some` elements are extracted in order.
Expand All @@ -57,7 +57,7 @@ IEnumerable<A> ToSequence(Seq<OptionUnsafe<A>> items)
}
return toSeq(ToSequence(self));
}

/// <summary>
/// Add the bound values of x and y, uses an Add type-class to provide the add
/// operation for type A. For example x.Add<TInteger,int>(y)
Expand All @@ -68,13 +68,13 @@ IEnumerable<A> ToSequence(Seq<OptionUnsafe<A>> items)
/// <param name="y">Right hand side of the operation</param>
/// <returns>An option with y added to x</returns>
[Pure]
public static OptionUnsafe<A> Add<NUM, A>(this OptionUnsafe<A> x, OptionUnsafe<A> y) where NUM : struct, Num<A> =>
public static OptionUnsafe<A> Add<ARITH, A>(this OptionUnsafe<A> x, OptionUnsafe<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select plus<NUM, A>(a, b);
select plus<ARITH, A>(a, b);

/// <summary>
/// Find the subtract between the two bound values of x and y, uses a Subtract type-class
/// Find the subtract between the two bound values of x and y, uses a Subtract type-class
/// to provide the subtract operation for type A. For example x.Subtract<TInteger,int>(y)
/// </summary>
/// <typeparam name="DIFF">Subtract of A</typeparam>
Expand All @@ -83,13 +83,13 @@ from b in y
/// <param name="y">Right hand side of the operation</param>
/// <returns>An OptionUnsafe with the subtract between x and y</returns>
[Pure]
public static OptionUnsafe<A> Subtract<NUM, A>(this OptionUnsafe<A> x, OptionUnsafe<A> y) where NUM : struct, Num<A> =>
public static OptionUnsafe<A> Subtract<ARITH, A>(this OptionUnsafe<A> x, OptionUnsafe<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select subtract<NUM, A>(a, b);
select subtract<ARITH, A>(a, b);

/// <summary>
/// Find the product between the two bound values of x and y, uses a Product type-class
/// Find the product between the two bound values of x and y, uses a Product type-class
/// to provide the product operation for type A. For example x.Product<TInteger,int>(y)
/// </summary>
/// <typeparam name="PROD">Product of A</typeparam>
Expand All @@ -98,10 +98,10 @@ from b in y
/// <param name="y">Right hand side of the operation</param>
/// <returns>An OptionUnsafe with the product of x and y</returns>
[Pure]
public static OptionUnsafe<A> Product<NUM, A>(this OptionUnsafe<A> x, OptionUnsafe<A> y) where NUM : struct, Num<A> =>
public static OptionUnsafe<A> Product<ARITH, A>(this OptionUnsafe<A> x, OptionUnsafe<A> y) where ARITH : struct, Arithmetic<A> =>
from a in x
from b in y
select product<NUM, A>(a, b);
select product<ARITH, A>(a, b);

/// <summary>
/// Divide the two bound values of x and y, uses a Divide type-class to provide the divide
Expand Down Expand Up @@ -302,7 +302,7 @@ public static A Sum<NUM, A>(this OptionUnsafe<A> self)
sum<NUM, MOptionUnsafe<A>, OptionUnsafe<A>, A>(self);

/// <summary>
/// Projection from one value to another
/// Projection from one value to another
/// </summary>
/// <typeparam name="B">Resulting functor value type</typeparam>
/// <param name="map">Projection function</param>
Expand All @@ -316,7 +316,7 @@ public static async Task<OptionUnsafe<B>> MapAsync<A, B>(this Task<OptionUnsafe<
}

/// <summary>
/// Projection from one value to another
/// Projection from one value to another
/// </summary>
/// <typeparam name="B">Resulting functor value type</typeparam>
/// <param name="map">Projection function</param>
Expand All @@ -330,7 +330,7 @@ public static async Task<OptionUnsafe<B>> MapAsync<A, B>(this Task<OptionUnsafe<
}

/// <summary>
/// Projection from one value to another
/// Projection from one value to another
/// </summary>
/// <typeparam name="B">Resulting functor value type</typeparam>
/// <param name="map">Projection function</param>
Expand All @@ -341,7 +341,7 @@ public static async Task<OptionUnsafe<B>> MapAsync<A, B>(this OptionUnsafe<Task<
: None;

/// <summary>
/// Projection from one value to another
/// Projection from one value to another
/// </summary>
/// <typeparam name="B">Resulting functor value type</typeparam>
/// <param name="map">Projection function</param>
Expand Down Expand Up @@ -436,7 +436,7 @@ public static async Task<int> CountAsync<A>(this Task<OptionUnsafe<A>> self) =>

/// <summary>
/// <para>
/// OptionUnsafe types are like lists of 0 or 1 items, and therefore follow the
/// OptionUnsafe types are like lists of 0 or 1 items, and therefore follow the
/// same rules when folding.
/// </para><para>
/// In the case of lists, 'Fold', when applied to a binary
Expand All @@ -458,7 +458,7 @@ public static async Task<S> FoldAsync<A, S>(this Task<OptionUnsafe<A>> self, S s

/// <summary>
/// <para>
/// OptionUnsafe types are like lists of 0 or 1 items, and therefore follow the
/// OptionUnsafe types are like lists of 0 or 1 items, and therefore follow the
/// same rules when folding.
/// </para><para>
/// In the case of lists, 'Fold', when applied to a binary
Expand All @@ -483,27 +483,27 @@ public static async Task<S> FoldAsync<A, S>(this OptionUnsafe<Task<A>> self, S s
/// <summary>
/// Apply a predicate to the bound value. If the OptionUnsafe is in a None state
/// then True is returned (because the predicate applies for-all values).
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the predicate supplied.
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the predicate supplied.
/// </summary>
/// <param name="pred"></param>
/// <returns>If the OptionUnsafe is in a None state then True is returned (because
/// <returns>If the OptionUnsafe is in a None state then True is returned (because
/// the predicate applies for-all values). If the OptionUnsafe is in a Some state
/// the value is the result of running applying the bound value to the
/// the value is the result of running applying the bound value to the
/// predicate supplied.</returns>
public static async Task<bool> ForAllAsync<A>(this Task<OptionUnsafe<A>> self, Func<A, bool> pred) =>
(await self.ConfigureAwait(false)).ForAll(pred);

/// <summary>
/// Apply a predicate to the bound value. If the OptionUnsafe is in a None state
/// then True is returned (because the predicate applies for-all values).
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the predicate supplied.
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the predicate supplied.
/// </summary>
/// <param name="pred"></param>
/// <returns>If the OptionUnsafe is in a None state then True is returned (because
/// <returns>If the OptionUnsafe is in a None state then True is returned (because
/// the predicate applies for-all values). If the OptionUnsafe is in a Some state
/// the value is the result of running applying the bound value to the
/// the value is the result of running applying the bound value to the
/// predicate supplied.</returns>
public static async Task<bool> ForAllAsync<A>(this OptionUnsafe<Task<A>> self, Func<A, bool> pred) =>
self.IsSome
Expand All @@ -513,27 +513,27 @@ public static async Task<bool> ForAllAsync<A>(this OptionUnsafe<Task<A>> self, F
/// <summary>
/// Apply a predicate to the bound value. If the OptionUnsafe is in a None state
/// then True is returned if invoking None returns True.
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the Some predicate supplied.
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the Some predicate supplied.
/// </summary>
/// <param name="pred"></param>
/// <returns>If the OptionUnsafe is in a None state then True is returned if
/// invoking None returns True. If the OptionUnsafe is in a Some state the value
/// is the result of running applying the bound value to the Some predicate
/// <returns>If the OptionUnsafe is in a None state then True is returned if
/// invoking None returns True. If the OptionUnsafe is in a Some state the value
/// is the result of running applying the bound value to the Some predicate
/// supplied.</returns>
public static async Task<bool> ExistsAsync<A>(this Task<OptionUnsafe<A>> self, Func<A, bool> pred) =>
(await self.ConfigureAwait(false)).Exists(pred);

/// <summary>
/// Apply a predicate to the bound value. If the OptionUnsafe is in a None state
/// then True is returned if invoking None returns True.
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the Some predicate supplied.
/// If the OptionUnsafe is in a Some state the value is the result of running
/// applying the bound value to the Some predicate supplied.
/// </summary>
/// <param name="pred"></param>
/// <returns>If the OptionUnsafe is in a None state then True is returned if
/// invoking None returns True. If the OptionUnsafe is in a Some state the value
/// is the result of running applying the bound value to the Some predicate
/// <returns>If the OptionUnsafe is in a None state then True is returned if
/// invoking None returns True. If the OptionUnsafe is in a Some state the value
/// is the result of running applying the bound value to the Some predicate
/// supplied.</returns>
public static async Task<bool> ExistsAsync<A>(this OptionUnsafe<Task<A>> self, Func<A, bool> pred) =>
self.IsSome
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static Try<A> Memo<A>(this Try<A> ma)
return ra;
};
}

/// <summary>
/// If the Try fails, retry `amount` times
/// </summary>
Expand All @@ -73,7 +73,7 @@ public static Try<A> Retry<A>(Try<A> ma, int amount = 3) => () =>
amount--;
if (amount <= 0) return ra;
}
};
};

/// <summary>
/// Forces evaluation of the lazy try
Expand Down Expand Up @@ -356,7 +356,7 @@ public static Unit Iter<A>(this Try<A> self, Action<A> action) =>
self.IfSucc(action);

/// <summary>
/// Counts the number of bound values.
/// Counts the number of bound values.
/// </summary>
/// <typeparam name="T">Type of the bound value</typeparam>
/// <param name="self">TrTry computation</param>
Expand Down Expand Up @@ -654,10 +654,10 @@ public static Result<T> Try<T>(this Try<T> self)
return new Result<T>(e);
}
}

[Pure]
public static Try<U> Use<T, U>(this Try<T> self, Func<T, U> select)
where T : IDisposable =>
where T : IDisposable =>
self.Map(x => use(x, select));

[Pure]
Expand Down Expand Up @@ -820,23 +820,23 @@ from y in rhs
/// <param name="rhs">Right-hand side of the operation</param>
/// <returns>lhs + rhs</returns>
[Pure]
public static Try<A> Add<NUM, A>(this Try<A> lhs, Try<A> rhs) where NUM : struct, Num<A> =>
public static Try<A> Add<ARITH, A>(this Try<A> lhs, Try<A> rhs) where ARITH : struct, Arithmetic<A> =>
from x in lhs
from y in rhs
select plus<NUM, A>(x, y);
select plus<ARITH, A>(x, y);

/// <summary>
/// Find the subtract of the bound value of Try(x) and Try(y). If either of
/// Find the subtract of the bound value of Try(x) and Try(y). If either of
/// the Trys are Fail then the result is Fail
/// </summary>
/// <param name="lhs">Left-hand side of the operation</param>
/// <param name="rhs">Right-hand side of the operation</param>
/// <returns>lhs + rhs</returns>
[Pure]
public static Try<A> Subtract<NUM, A>(this Try<A> lhs, Try<A> rhs) where NUM : struct, Num<A> =>
public static Try<A> Subtract<ARITH, A>(this Try<A> lhs, Try<A> rhs) where ARITH : struct, Arithmetic<A> =>
from x in lhs
from y in rhs
select subtract<NUM, A>(x, y);
select subtract<ARITH, A>(x, y);

/// <summary>
/// Multiply the bound value of Try(x) and Try(y). If either of the
Expand All @@ -846,10 +846,10 @@ from y in rhs
/// <param name="rhs">Right-hand side of the operation</param>
/// <returns>lhs + rhs</returns>
[Pure]
public static Try<A> Product<NUM, A>(this Try<A> lhs, Try<A> rhs) where NUM : struct, Num<A> =>
public static Try<A> Product<ARITH, A>(this Try<A> lhs, Try<A> rhs) where ARITH : struct, Arithmetic<A> =>
from x in lhs
from y in rhs
select product<NUM, A>(x, y);
select product<ARITH, A>(x, y);

/// <summary>
/// Multiply the bound value of Try(x) and Try(y). If either of the
Expand Down
Loading

0 comments on commit ef270f5

Please sign in to comment.