Refactored Option<T> to have opertator lifting and removed ref struct for now.
All checks were successful
Build NuGet / build (push) Successful in 1m43s
All checks were successful
Build NuGet / build (push) Successful in 1m43s
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
|
||||
namespace SJK.Functional;
|
||||
|
||||
public static class OptionExtensions
|
||||
public static partial class OptionExtensions
|
||||
{
|
||||
public static IEnumerable<TResult> Match<T, TResult>(this IEnumerable<IOption<T>> values, Func<T, TResult> onSome, Func<TResult> onNone)
|
||||
public static IEnumerable<TResult> Match<T, TResult>(this IEnumerable<Option<T>> values, Func<T, TResult> onSome, Func<TResult> onNone)
|
||||
{
|
||||
foreach (var item in values)
|
||||
{
|
||||
@@ -19,24 +20,24 @@ public static class OptionExtensions
|
||||
// }
|
||||
// return None<T>.Of();
|
||||
// }
|
||||
public static IOption<T> GetValue<Tkey, T>(this IReadOnlyDictionary<Tkey, T> value, Tkey key) where Tkey : notnull
|
||||
public static Option<T> GetValueOrNone<Tkey, T>(this IReadOnlyDictionary<Tkey, T> value, Tkey key) where Tkey : notnull
|
||||
{
|
||||
if (value.TryGetValue(key, out var v))
|
||||
{
|
||||
return v.ToOption();
|
||||
}
|
||||
return None<T>.Of();
|
||||
return Option<T>.None;
|
||||
}
|
||||
public static IOption<T> OrElse<T>(this IOption<T> option, Func<IOption<T>> fallback)
|
||||
{
|
||||
return option.Match(
|
||||
some => option,
|
||||
() => fallback()
|
||||
);
|
||||
}
|
||||
public static IOption<TResult> BindUsing<TDisposable, TResult>(
|
||||
this IOption<TDisposable> option,
|
||||
Func<TDisposable, IOption<TResult>> func)
|
||||
// public static Option<T> OrElse<T>(this Option<T> option, Func<Option<T>> fallback)
|
||||
// {
|
||||
// return option.Match(
|
||||
// some => option,
|
||||
// () => fallback()
|
||||
// );
|
||||
// }
|
||||
public static Option<TResult> BindUsing<TDisposable, TResult>(
|
||||
this Option<TDisposable> option,
|
||||
Func<TDisposable, Option<TResult>> func)
|
||||
where TDisposable : IDisposable
|
||||
{
|
||||
return option.Match(
|
||||
@@ -44,48 +45,48 @@ public static class OptionExtensions
|
||||
{
|
||||
using (some) return func(some);
|
||||
},
|
||||
() => None<TResult>.Of()
|
||||
() => Option<TResult>.None
|
||||
);
|
||||
}
|
||||
|
||||
public static IOption<T> ToOption<T>(this T? value) => value != null ? Some<T>.Of(value) : None<T>.Of();
|
||||
[StackTraceHidden]
|
||||
// public static IOption<T> ToOption<T>(this T? value) => value != null ? Some<T>.Of(value) : None<T>.Of();
|
||||
// [StackTraceHidden]
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T OrThrow<T, TEx>(this IOption<T> option, Func<TEx> exceptionFactory) where TEx : Exception
|
||||
{
|
||||
if (option.HasValue(out var value))
|
||||
return value;
|
||||
// public static T OrThrow<T, TEx>(this IOption<T> option, Func<TEx> exceptionFactory) where TEx : Exception
|
||||
// {
|
||||
// if (option.HasValue(out var value))
|
||||
// return value;
|
||||
|
||||
throw exceptionFactory();
|
||||
}
|
||||
public static IEither<L, R> ToEither<Tvalue, L, R>(this Tvalue value, Func<Tvalue, bool> isSuccess, Func<R> ok, Func<Tvalue, L> err)
|
||||
{
|
||||
return isSuccess(value) ? new Right<L, R>(ok()) : new Left<L, R>(err(value));
|
||||
}
|
||||
public static IEither<L, R> ToEither<Tvalue, L, R>(this Tvalue value, Tvalue successValue, Func<R> ok, Func<Tvalue, L> err) where Tvalue : notnull
|
||||
{
|
||||
return value.ToEither(e => e.Equals(successValue), ok, err);
|
||||
}
|
||||
// throw exceptionFactory();
|
||||
// }
|
||||
// public static IEither<L, R> ToEither<Tvalue, L, R>(this Tvalue value, Func<Tvalue, bool> isSuccess, Func<R> ok, Func<Tvalue, L> err)
|
||||
// {
|
||||
// return isSuccess(value) ? new Right<L, R>(ok()) : new Left<L, R>(err(value));
|
||||
// }
|
||||
// public static IEither<L, R> ToEither<Tvalue, L, R>(this Tvalue value, Tvalue successValue, Func<R> ok, Func<Tvalue, L> err) where Tvalue : notnull
|
||||
// {
|
||||
// return value.ToEither(e => e.Equals(successValue), ok, err);
|
||||
// }
|
||||
// public static IEnumerable<IOption<T>> ToOptions<T>(this IEnumerable<T> value) => value.Select(thing => thing.ToOption());
|
||||
public static Some<T> ToSome<T>(this T value) where T : notnull => Some<T>.Of(value);
|
||||
public static void IfSome<T>(this IOption<T> value, Action<T> onSome) => value.Match(onSome, () => { });
|
||||
public static void IfNone<T>(this IOption<T> value, Action onNone) => value.Match(_ => { }, onNone);
|
||||
// public static Some<T> ToSome<T>(this T value) where T : notnull => Some<T>.Of(value);
|
||||
// public static void IfSome<T>(this IOption<T> value, Action<T> onSome) => value.Match(onSome, () => { });
|
||||
// public static void IfNone<T>(this IOption<T> value, Action onNone) => value.Match(_ => { }, onNone);
|
||||
|
||||
public static T Or<T>(this IOption<T> value, Func<T> @default) => value.Or(@default());
|
||||
public static IEnumerable<T> OnlySomes<T>(this IEnumerable<IOption<T>> options)
|
||||
// public static T Or<T>(this IOption<T> value, Func<T> @default) => value.Or(@default());
|
||||
public static IEnumerable<T> OnlySomes<T>(this IEnumerable<Option<T>> options)
|
||||
{
|
||||
foreach (var item in options)
|
||||
{
|
||||
if (item.HasValue(out var item2))
|
||||
yield return item2;
|
||||
if (item.HasValue)
|
||||
yield return item.Value;
|
||||
}
|
||||
}
|
||||
// public static None<T> ToNone<T>(this T value) => None<T>.Of();
|
||||
|
||||
public static Option<T> ToStructOption<T>(this IOption<T> option) => option.HasValue(out var value) ? Option<T>.Some(value) : Option<T>.None;
|
||||
public static IOption<T> ToClassOption<T>(this Option<T> option) => option.HasValue ? option.Value.ToOption() : None<T>.Of();
|
||||
public static IOption<T> FirstOrNone<T>(this IEnumerable<T> options) => options.Any() ? options.First().ToOption() : None<T>.Of();
|
||||
public static IOption<T> FirstOrNone<T>(this IEnumerable<T> options, Predicate<T> predicate)
|
||||
// public static Option<T> ToStructOption<T>(this IOption<T> option) => option.HasValue(out var value) ? Option<T>.Some(value) : Option<T>.None;
|
||||
// public static IOption<T> ToClassOption<T>(this Option<T> option) => option.HasValue ? option.Value.ToOption() : None<T>.Of();
|
||||
public static Option<T> FirstOrNone<T>(this IEnumerable<T> options) => options.Any() ? options.First().ToOption() : Option<T>.None;
|
||||
public static Option<T> FirstOrNone<T>(this IEnumerable<T> options, Predicate<T> predicate)
|
||||
{
|
||||
foreach (var item in options)
|
||||
{
|
||||
@@ -94,6 +95,84 @@ public static class OptionExtensions
|
||||
return item.ToOption();
|
||||
}
|
||||
}
|
||||
return None<T>.Of();
|
||||
return Option<T>.None;
|
||||
}
|
||||
public static Option<T> ToOption<T>(this T? value) => value is null ? Option<T>.None : Option<T>.Some(value);
|
||||
|
||||
|
||||
public static Option<T2> TryGetValue<T,T2>(this Option<IDictionary<T,T2>> option, T key) => option.Map(f => f.TryGetValue(key, out var result)?Option.Some(result):Option.None<T2>());
|
||||
|
||||
|
||||
extension<T>(Option<T>) where T : IAdditionOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator +(Option<T> left, T right) => left.Map(f => f + right);
|
||||
}
|
||||
extension<T>(Option<T>) where T : ISubtractionOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator -(Option<T> left, T right) => left.Map(f => f - right);
|
||||
}
|
||||
|
||||
extension<T>(Option<T>) where T : IMultiplyOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator *(Option<T> left, T right) => left.Map(f => f *right);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IDivisionOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator /(Option<T> left, T right) => left.Map(f => f / right);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IIncrementOperators<T>
|
||||
{
|
||||
public static Option<T> operator ++(Option<T> left) => left.Map(f => f++);
|
||||
}
|
||||
|
||||
extension<T>(Option<T>) where T : IDecrementOperators<T>
|
||||
{
|
||||
public static Option<T> operator --(Option<T> left) => left.Map(f => f--);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IModulusOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator %(Option<T> left, T right) => left.Map(f => f % right);
|
||||
}
|
||||
extension<T>(Option<T> _) where T : IShiftOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator <<(Option<T> left, T right) => left.Map(f => f << right);
|
||||
public static Option<T> operator >>(Option<T> left, T right) => left.Map(f => f >> right);
|
||||
public static Option<T> operator >>>(Option<T> left, T right) => left.Map(f => f >>> right);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IBitwiseOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator &(Option<T> left, T right) => left.Map(f => f & right);
|
||||
public static Option<T> operator |(Option<T> left, T right) => left.Map(f => f | right);
|
||||
public static Option<T> operator ^(Option<T> left, T right) => left.Map(f => f ^ right);
|
||||
public static Option<T> operator ~(Option<T> left) => left.Map(f => ~f);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IComparisonOperators<T,T,T>
|
||||
{
|
||||
public static Option<T> operator >(Option<T> left, T right) => left.Map(f => f > right);
|
||||
public static Option<T> operator <(Option<T> left, T right) => left.Map(f => f < right);
|
||||
public static Option<T> operator >=(Option<T> left, T right) => left.Map(f => f >= right);
|
||||
public static Option<T> operator <=(Option<T> left, T right) => left.Map(f => f <= right);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IUnaryPlusOperators<T,T>
|
||||
{
|
||||
public static Option<T> operator +(Option<T> left) => left.Map(f => +f);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IUnaryNegationOperators<T,T>
|
||||
{
|
||||
public static Option<T> operator -(Option<T> left) => left.Map(f => -f);
|
||||
}
|
||||
extension<T>(in Option<T> option) where T : IComparable<T>
|
||||
{
|
||||
public int CompareTo(T? value) => option.Map(f => f.CompareTo(value));
|
||||
}
|
||||
extension<T>(in Option<T> option) where T : IParsable<T>
|
||||
{
|
||||
public static Option<T> TryParse(in string? value, IFormatProvider formatProvider) => T.TryParse(value, formatProvider, out var result)?Option.Some(result):Option.None<T>();
|
||||
public static Option<T> Parse(in string value, IFormatProvider formatProvider) => T.Parse(value, formatProvider);
|
||||
}
|
||||
extension<T>(Option<T>) where T : IEqualityOperators<T,T,bool>
|
||||
{
|
||||
public static Option<bool> operator ==(Option<T> left, T right) => left.Map(f => f == right);
|
||||
public static Option<bool> operator !=(Option<T> left, T right) => left.Map(f => f != right);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user