using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; namespace SJK.Functional; public interface IOption { T? Value {get;} [MemberNotNullWhen(true,nameof(Value))] bool HasValue {get;} } // public interface K where F : allows ref struct; // public interface K : K where TSelf : K, allows ref struct where F : allows ref struct; // public interface Functor // where F : Functor, allows ref struct // { // // public static abstract K Map(Func f, K thing); // public static abstract TFunctor Map(Func f, TSource thing) where TFunctor : K, allows ref struct where TSource : K, 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 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 tostring = f=>f.Contains('5'); // var res = Option.Map(a,tostring); // var opt = RefOption.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.Some(5).Match( (int f) => f.ToString(), () => "none"); // Option.None.IfSome((int some) => {}); // Option.None.Map((some) => some.ToString()); // Option.None.Bind((some) => Option.Some(some.ToString())); // int num = 5; // string num2 = "gg"; // RefOption.Some(ref num).Match( (int f) => f.ToString(), () => "none"); // RefOption.None.IfSome((int some) => {}); // RefOption.None.Map((some) => some.ToString()); // RefOption.None.Bind((some) => Option.Some(some.ToString())); // RefOption.None.Map((ref some) => ref hello); // RefOption.None.Bind((ref some) => RefOption.Some(ref hello)); // Option result = Option.Some(5).Map(f => f.ToString()); // RefOption result2 = RefOption.Some(ref num2); // // Option res = Option.Map( f => f.Length,result).As(); // int test(string value)=>value.Length; // Func factory = test; // var a = factory.Map(result); // var aa = result2.MapRef(factory); // // IOptionCase classOption = new Some("5"); // // IOptionCase classOption1 = classOption; // // var result = classOption1 switch // // { // // Some some => some.Value, // // None none => "None", // // _ => "hello" // // }; // } // // extension(TSource source) where TSource : K // // { // // public static TFunctor As(TSource self) where TFunctor : => self; // // } // public static Option As(this K self) => (Option) self; // // public static K map(Func f, K fa) where F : Functor => F.Map(f,fa); // public static TFunctor map(Func f, TSource fa) where F : Functor, allows ref struct where TSource : K, allows ref struct where TFunctor : K, allows ref struct => F.Map(f,fa); // public static Option Map(this Func f, TSource ma) where TSource : K, allows ref struct => map,TSource>(f,ma).As(); // public static Option Map(this TSource ma, Func f) where TSource : K, allows ref struct => map,TSource>(f,ma).As(); // // public static RefOption MapRef(this TSource ma, RefOption.RefSelector f) where TSource : K, allows ref struct => map,TSource>(f,ma); // public static TFunctor Map(this Func f, TSource ma) where TSource : K, allows ref struct where TFunctor : K, allows ref struct => map(f,ma); // public static TFunctor Map(this TSource ma, Func f) where TSource : K, allows ref struct where TFunctor : K, allows ref struct => map(f,ma); // // public static TFunctor MapRef(this RefOption.RefSelector f, TSource ma) where TSource : K, allows ref struct where TFunctor : K, allows ref struct => map(f,ma); // // extension(Func f) // // { // // // public static TFunctor Map( TSource ma) where TSource : K, allows ref struct where TFunctor : K, allows ref struct => map(f,ma); // // } // // public static Option Map(this Func f, K> ma) => map>,A,B,Option,(f,ma).As(); // public static Option ToOption(this T? value) where T : class => value is null ? Option.None : Option.Some(value); // public static Option ToOption(this T? value) where T : struct => !value.HasValue ? Option.None : Option.Some(value.Value); // public static void IfSome(this TOption option, Action action) where TOption : struct, IOption, allows ref struct //where T : allows ref struct // { // if (option.HasValue) // { // action(option.Value); // } // } // // public static IOptionCase ToCase(this IOption option) => option.HasValue ? new Some(option.Value) : None.Of; // // public static TOptionResult Map(this TOption self, Func f) // // where TOption : IOption, allows ref struct // // where TOptionResult : IOption, allows ref struct // // => self.HasValue ? TOptionResult.Some(f(self.Value)) : TOptionResult.None; // // public static TOptionResult Bind(this TOption self, Func f) // // where TOption : IOption, allows ref struct // // where TOptionResult : IOption, allows ref struct // // => self.HasValue ? f(self.Value) : TOptionResult.None; // public static TResult Match(this TSelf self, Func onSome, Func onNone) where TSelf : IOption, allows ref struct // => self.HasValue ? onSome(self.Value) : onNone(); // public static void IfNone(this TOption option, Action action) where TOption : struct, IOption, allows ref struct //where T : allows ref struct // { // if (!option.HasValue) // { // action(); // } // } // public static TOption GetValueOrNone(this IDictionary dict, TKey key) where TKey : notnull where T : IEquatable where TOption : struct, IOption, allows ref struct // { // if (dict.TryGetValue(key, out var result)) // { // return TOption.Some(result); // } // return TOption.None; // } // public static bool TryGetValue(this TOption option,[NotNullWhen(true)] out T? value) where TOption : struct, IOption, allows ref struct // { // value = option.Value; // return false; // } // // public static TOption BindAs(this TSelf self) where TSelf : IOption, allows ref struct where TOption : IOption => self.HasValue ? TOption.Some(self.Value) : TOption.None; // // public static TOption BindAs(this TSelf option, Func f) // // where TSelf : IOption // // where TOption : IOption => // // option.HasValue?f(option.Value) : TOption.None; // public static T? ToNullable(this IOption option) where T : struct // { // if (option.HasValue) // { // return option.Value; // } // return default; // } // public static T Or(this TSelf option, T @default) where TSelf : struct, IOption, allows ref struct => option.HasValue ? option.Value : @default; // public static T OrDefault(this TSelf option, Func @default) where TSelf : struct, IOption , allows ref struct => option.HasValue ? option.Value : @default(); // } public interface IOption : IOption/*, IEquatable*/ where TSelf : IOption//, allows ref struct { // void Match(Action onSome,Action onNone); // IOption Bind(Func> f); // TSelf Map(Func f) where TOptionResult : IOption where TResult : allows ref struct; // T Or(Func aDefault); // [MemberNotNullWhen(true,nameof(HasValue))] // T Value {get;} public static abstract TSelf Some(T value); public static abstract TSelf None {get;} // public TOption BindAs()where TOption : IOption, allows ref struct => HasValue ? TOption.Some(Value) : TOption.None; } public class Option //: Functor