280 lines
14 KiB
C#
280 lines
14 KiB
C#
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Numerics;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace SJK.Functional;
|
|
public interface IOption<out T>
|
|
{
|
|
T? Value {get;}
|
|
[MemberNotNullWhen(true,nameof(Value))]
|
|
bool HasValue {get;}
|
|
}
|
|
// public interface K<in F,A> where F : allows ref struct;
|
|
// public interface K<in F,A, TSelf> : K<F,A> where TSelf : K<F,A,TSelf>, allows ref struct where F : allows ref struct;
|
|
// public interface Functor<F>
|
|
// where F : Functor<F>, allows ref struct
|
|
// {
|
|
// // public static abstract K<F,B> Map<A, B>(Func<A,B> f, K<F,A> thing);
|
|
// public static abstract TFunctor Map<A, B,TFunctor,TSource>(Func<A,B> f, TSource thing) where TFunctor : K<F,B,TFunctor>, allows ref struct where TSource : K<F,A,TSource>, allows ref struct;
|
|
// }
|
|
// public static partial class OptionExtensions
|
|
// {
|
|
// static string hello = "world";
|
|
// struct testttt
|
|
// {
|
|
// public int gg;
|
|
// }
|
|
// public static void tt()
|
|
// {
|
|
// var gg = new testttt();
|
|
// var t = Option.SomeRef(ref gg).Map((ref f) => ref f.gg).Map(f => f.ToString());
|
|
// Func<int,string> tostring = f=>f.ToString();
|
|
// Option.Map(tostring, t);
|
|
// gg.gg = 5;
|
|
// var a = Option.Some(5).Map(f => f.ToString()).Map(f => f + f);
|
|
// Func<string,bool> tostring = f=>f.Contains('5');
|
|
// var res = Option.Map(a,tostring);
|
|
// var opt = RefOption<testttt>.Some(ref gg);
|
|
// var r = opt.MapRef(f => ref f.gg);
|
|
// opt.MapRef()
|
|
// var s = tostring.Map(opt);
|
|
// if (s.HasValue)
|
|
// {
|
|
// Console.WriteLine(s.Value);
|
|
// }
|
|
// Option<int>.Some(5).Match( (int f) => f.ToString(), () => "none");
|
|
// Option<int>.None.IfSome((int some) => {});
|
|
// Option<int>.None.Map((some) => some.ToString());
|
|
// Option<int>.None.Bind((some) => Option<string>.Some(some.ToString()));
|
|
// int num = 5;
|
|
// string num2 = "gg";
|
|
// RefOption<int>.Some(ref num).Match( (int f) => f.ToString(), () => "none");
|
|
// RefOption<int>.None.IfSome((int some) => {});
|
|
// RefOption<int>.None.Map((some) => some.ToString());
|
|
// RefOption<int>.None.Bind((some) => Option<string>.Some(some.ToString()));
|
|
// RefOption<int>.None.Map((ref some) => ref hello);
|
|
// RefOption<int>.None.Bind((ref some) => RefOption<string>.Some(ref hello));
|
|
|
|
// Option<string> result = Option.Some(5).Map(f => f.ToString());
|
|
// RefOption<string> result2 = RefOption<string>.Some(ref num2);
|
|
// // Option<int> res = Option.Map( f => f.Length,result).As();
|
|
// int test(string value)=>value.Length;
|
|
// Func<string,int> factory = test;
|
|
// var a = factory.Map(result);
|
|
// var aa = result2.MapRef(factory);
|
|
// // IOptionCase<string> classOption = new Some<string>("5");
|
|
// // IOptionCase<object> classOption1 = classOption;
|
|
// // var result = classOption1 switch
|
|
// // {
|
|
// // Some<string> some => some.Value,
|
|
// // None none => "None",
|
|
// // _ => "hello"
|
|
// // };
|
|
// }
|
|
// // extension<TSource,T>(TSource source) where TSource : K<Option,T,TSource>
|
|
// // {
|
|
// // public static TFunctor As<TFunctor>(TSource self) where TFunctor : => self;
|
|
|
|
// // }
|
|
// public static Option<T> As<T>(this K<Option,T> self) => (Option<T>) self;
|
|
// // public static K<F,B> map<F,A,B>(Func<A,B> f, K<F,A> fa) where F : Functor<F> => F.Map(f,fa);
|
|
// public static TFunctor map<F,A,B,TFunctor,TSource>(Func<A,B> f, TSource fa) where F : Functor<F>, allows ref struct where TSource : K<F,A,TSource>, allows ref struct where TFunctor : K<F,B,TFunctor>, allows ref struct => F.Map<A,B,TFunctor,TSource>(f,fa);
|
|
// public static Option<B> Map<A,B,TSource>(this Func<A,B> f, TSource ma) where TSource : K<Option,A,TSource>, allows ref struct => map<Option,A,B,Option<B>,TSource>(f,ma).As();
|
|
// public static Option<B> Map<A,B,TSource>(this TSource ma, Func<A,B> f) where TSource : K<Option,A,TSource>, allows ref struct => map<Option,A,B,Option<B>,TSource>(f,ma).As();
|
|
// // public static RefOption<B> MapRef<A,B,TSource>(this TSource ma, RefOption<A>.RefSelector<B> f) where TSource : K<Option,A,TSource>, allows ref struct => map<Option,A,B,RefOption<B>,TSource>(f,ma);
|
|
// public static TFunctor Map<A,B,TSource,TFunctor>(this Func<A,B> f, TSource ma) where TSource : K<Option,A,TSource>, allows ref struct where TFunctor : K<Option,B,TFunctor>, allows ref struct => map<Option,A,B,TFunctor,TSource>(f,ma);
|
|
// public static TFunctor Map<A,B,TSource,TFunctor>(this TSource ma, Func<A,B> f) where TSource : K<Option,A,TSource>, allows ref struct where TFunctor : K<Option,B,TFunctor>, allows ref struct => map<Option,A,B,TFunctor,TSource>(f,ma);
|
|
// // public static TFunctor MapRef<A,B,TSource,TFunctor>(this RefOption<A>.RefSelector<B> f, TSource ma) where TSource : K<Option,A,TSource>, allows ref struct where TFunctor : K<Option,B,TFunctor>, allows ref struct => map<Option,A,B,TFunctor,TSource>(f,ma);
|
|
// // extension<A,B>(Func<A,B> f)
|
|
// // {
|
|
// // // public static TFunctor Map<TSource,TFunctor>( TSource ma) where TSource : K<Option,A,TSource>, allows ref struct where TFunctor : K<Option,B,TFunctor>, allows ref struct => map<Option,A,B,TFunctor,TSource>(f,ma);
|
|
|
|
// // }
|
|
// // public static Option<B> Map<A,B>(this Func<A,B> f, K<Option,A,Option<A>> ma) => map<K<Option,A,Option<A>>,A,B,Option<B>,(f,ma).As();
|
|
// public static Option<T> ToOption<T,TOption>(this T? value) where T : class => value is null ? Option<T>.None : Option<T>.Some(value);
|
|
// public static Option<T> ToOption<T,TOption>(this T? value) where T : struct => !value.HasValue ? Option<T>.None : Option<T>.Some(value.Value);
|
|
// public static void IfSome<T, TOption>(this TOption option, Action<T> action) where TOption : struct, IOption<TOption, T>, allows ref struct //where T : allows ref struct
|
|
// {
|
|
// if (option.HasValue)
|
|
// {
|
|
// action(option.Value);
|
|
// }
|
|
// }
|
|
// // public static IOptionCase<T> ToCase<T>(this IOption<T> option) => option.HasValue ? new Some<T>(option.Value) : None<T>.Of;
|
|
// // public static TOptionResult Map<TOption,TResult,T,TOptionResult>(this TOption self, Func<T, TResult> f)
|
|
// // where TOption : IOption<T>, allows ref struct
|
|
// // where TOptionResult : IOption<TOptionResult,TResult>, allows ref struct
|
|
// // => self.HasValue ? TOptionResult.Some(f(self.Value)) : TOptionResult.None;
|
|
// // public static TOptionResult Bind<TOption,TResult,T,TOptionResult>(this TOption self, Func<T, TOptionResult> f)
|
|
// // where TOption : IOption<T>, allows ref struct
|
|
// // where TOptionResult : IOption<TOptionResult,TResult>, allows ref struct
|
|
// // => self.HasValue ? f(self.Value) : TOptionResult.None;
|
|
|
|
// public static TResult Match<TSelf, TResult, T>(this TSelf self, Func<T, TResult> onSome, Func<TResult> onNone) where TSelf : IOption<T>, allows ref struct
|
|
// => self.HasValue ? onSome(self.Value) : onNone();
|
|
// public static void IfNone<T, TOption>(this TOption option, Action action) where TOption : struct, IOption<TOption, T>, allows ref struct //where T : allows ref struct
|
|
// {
|
|
// if (!option.HasValue)
|
|
// {
|
|
// action();
|
|
// }
|
|
// }
|
|
// public static TOption GetValueOrNone<TKey,T,TOption>(this IDictionary<TKey,T> dict, TKey key) where TKey : notnull where T : IEquatable<T> where TOption : struct, IOption<TOption,T>, allows ref struct
|
|
// {
|
|
// if (dict.TryGetValue(key, out var result))
|
|
// {
|
|
// return TOption.Some(result);
|
|
// }
|
|
// return TOption.None;
|
|
// }
|
|
// public static bool TryGetValue<T,TOption>(this TOption option,[NotNullWhen(true)] out T? value) where TOption : struct, IOption<TOption,T>, allows ref struct
|
|
// {
|
|
// value = option.Value;
|
|
// return false;
|
|
// }
|
|
// // public static TOption BindAs<TOption,T,TSelf>(this TSelf self) where TSelf : IOption<T>, allows ref struct where TOption : IOption<TOption,T> => self.HasValue ? TOption.Some(self.Value) : TOption.None;
|
|
// // public static TOption BindAs<TSelf,T,TOption,TResult>(this TSelf option, Func<T,TOption> f)
|
|
// // where TSelf : IOption<TSelf,T>
|
|
// // where TOption : IOption<TOption,TResult> =>
|
|
// // option.HasValue?f(option.Value) : TOption.None;
|
|
// public static T? ToNullable<T>(this IOption<T> option) where T : struct
|
|
// {
|
|
// if (option.HasValue)
|
|
// {
|
|
// return option.Value;
|
|
// }
|
|
// return default;
|
|
// }
|
|
// public static T Or<TSelf,T>(this TSelf option, T @default) where TSelf : struct, IOption<T>, allows ref struct => option.HasValue ? option.Value : @default;
|
|
// public static T OrDefault<TSelf,T>(this TSelf option, Func<T> @default) where TSelf : struct, IOption<T> , allows ref struct => option.HasValue ? option.Value : @default();
|
|
|
|
// }
|
|
public interface IOption<TSelf,T> : IOption<T>/*, IEquatable<TSelf>*/ where TSelf : IOption<TSelf,T>//, allows ref struct
|
|
{
|
|
// void Match(Action<T> onSome,Action onNone);
|
|
// IOption<TResult> Bind<TResult>(Func<T, IOption<TResult>> f);
|
|
// TSelf Map<TOptionResult,TResult>(Func<T, TResult> f) where TOptionResult : IOption<TOptionResult,TResult> where TResult : allows ref struct;
|
|
// T Or(Func<T> aDefault);
|
|
// [MemberNotNullWhen(true,nameof(HasValue))]
|
|
// T Value {get;}
|
|
public static abstract TSelf Some(T value);
|
|
public static abstract TSelf None {get;}
|
|
// public TOption BindAs<TOption>()where TOption : IOption<TOption,T>, allows ref struct => HasValue ? TOption.Some(Value) : TOption.None;
|
|
}
|
|
public class Option //: Functor<Option>
|
|
{
|
|
// public static K<Option, B> Map<A, B>(Func<A, B> f, K<Option, A> thing)
|
|
// {
|
|
// return thing.As().Map(f);
|
|
// }
|
|
|
|
// public static TFunctor Map<A, B, TFunctor>(Func<A, B> f, K<Option, A> thing) where TFunctor : K<Option, B>
|
|
// {
|
|
// return thing.As().Map(f);
|
|
// }
|
|
|
|
// public static TFunctor Map<A, B, TFunctor, TSource>(Func<A, B> f, TSource thing)
|
|
// where TFunctor : K<Option, B, TFunctor>, allows ref struct
|
|
// where TSource : K<Option, A, TSource>, allows ref struct
|
|
// {
|
|
// return f.Map<A,B,TSource,TFunctor>(thing);
|
|
// }
|
|
|
|
public static Option<T> Some<T>(T value) => Option<T>.Some(value);
|
|
public static Option<T> None<T>() => Option<T>.None;
|
|
// public static RefOption<T> SomeRef<T>(ref T value) => RefOption<T>.Some(ref value);
|
|
// public static RefOption<T> NoneRef<T>() => RefOption<T>.None;
|
|
|
|
}
|
|
// public interface IRefStruct<TSelf,T> where TSelf : IRefStruct<TSelf,T>, allows ref struct
|
|
// {
|
|
|
|
// }
|
|
// public readonly ref struct RefOption<T> : IRefStruct<RefOption<T>,T>, IOption<RefOption<T>, T>,K<Option,T,RefOption<T>>// where T : IEquatable<T>//, allows ref struct
|
|
// {
|
|
// public readonly ref T? Value => ref _value;
|
|
// readonly T? IOption<T>.Value => _value;
|
|
// private readonly ref T? _value;
|
|
|
|
// private RefOption(ref T value, bool hasValue) : this()
|
|
// {
|
|
// _value = value;
|
|
// HasValue = hasValue;
|
|
// }
|
|
// private RefOption(T value, bool hasValue) : this()
|
|
// {
|
|
// _value = value;
|
|
// HasValue = hasValue;
|
|
// }
|
|
// public RefOption()
|
|
// {
|
|
// HasValue = false;
|
|
// _value = default!;
|
|
// }
|
|
|
|
// [MemberNotNullWhen(true,nameof(Value), nameof(_value), nameof(IOption<T>.Value))]
|
|
|
|
// public bool HasValue {get; init;}
|
|
|
|
// public unsafe readonly RefOption<TResult> MapUnsafe<TResult>(delegate*<ref T, ref TResult> f)
|
|
// // where TResult : unmanaged, IEquatable<TResult>//, allows ref struct
|
|
// =>
|
|
// HasValue ? RefOption<TResult>.Some(ref f(ref _value)) : RefOption<TResult>.None;
|
|
|
|
// public unsafe readonly RefOption<TResult> BindUnsafe<TResult>(delegate*<ref T, RefOption<TResult>> f)
|
|
// // where TResult : unmanaged, IEquatable<TResult>//, allows ref struct
|
|
// =>
|
|
// HasValue ? f(ref _value) : RefOption<TResult>.None;
|
|
// public readonly RefOption<TResult> Bind<TResult>(RefBinder<TResult> f ) => HasValue ? f(ref Value) : RefOption<TResult>.None;
|
|
// public readonly Option<TResult> Bind<TResult>(Func<T,TResult> f) => HasValue ? Option<TResult>.Some(f(_value)) : Option<TResult>.None;
|
|
// public static RefOption<T> Some(ref T value) => new(ref value,false);
|
|
// // public static RefOption<T> Some(T value) => new(value,false);
|
|
// public static RefOption<T> None => new();
|
|
|
|
|
|
|
|
// // public T OrDefault(T aDefault) => HasValue?_value:aDefault;
|
|
|
|
// // public TResult Match<TResult>(Func<T, TResult> onSome, Func<TResult> onNone)
|
|
// // => HasValue ? onSome(_value) : onNone();
|
|
|
|
// // public T Or(Func<T> aDefault)
|
|
// // => HasValue ? _value : aDefault();
|
|
|
|
// public bool Equals(RefOption<T> other)
|
|
// {
|
|
// return other.HasValue == HasValue && EqualityComparer<T>.Default.Equals(_value,other._value);
|
|
// }
|
|
|
|
// // public readonly TOption Map<TResult, TOption>(Func<T, TResult> f) where TOption : IOption<TOption, TResult> => HasValue ? TOption.Some(f(_value)) : TOption.None;
|
|
// public readonly Option<TResult> Map<TResult>(Func<T, TResult> f) => HasValue ? Option<TResult>.Some(f(Value)) : Option<TResult>.None;
|
|
// public readonly RefOption<TResult> Map<TResult>(RefSelector<TResult> f) => HasValue ? RefOption<TResult>.Some(ref f(ref Value)) : RefOption<TResult>.None;
|
|
// public TOption BindAs<TOption>() where TOption : IOption<TOption,T> => HasValue ? TOption.Some(Value) : TOption.None;
|
|
|
|
// static RefOption<T> IOption<RefOption<T>, T>.Some(T value) => new(value,false);
|
|
// public delegate RefOption<TResult> RefBinder<TResult>( ref T source);
|
|
// public delegate ref TResult RefSelector<TResult>(ref T value);
|
|
// /// <summary>
|
|
// /// Maps the Option, resulting a not ref struct vesion being boxed and returned
|
|
// /// </summary>
|
|
// /// <typeparam name="TResult"></typeparam>
|
|
// /// <param name="f"></param>
|
|
// /// <returns></returns>
|
|
// // IOption<TResult> IOption<T>.Map<TResult>(Func<T, TResult> f) => HasValue ? Some<TResult>.Of(f(_value)) : None<TResult>.Of;
|
|
|
|
// // public bool TryGetValue(out T value)
|
|
// // {
|
|
// // if (HasValue)
|
|
// // {
|
|
// // value = Value;
|
|
// // return true;
|
|
// // }
|
|
// // value = default;
|
|
// // return false;
|
|
// // }
|
|
|
|
|
|
// // public static implicit operator RefStruct<T>(T value) => Some(value);
|
|
// } |