using System.Diagnostics.CodeAnalysis; namespace SJK.Functional; public readonly struct Option : IOption, IOption, T>//, // K>, // IEquatable> { private readonly T? _value; private Option(T? value, bool hasValue) { _value = value; HasValue = hasValue; } public static Option None => new Option(default!,false); public T? Value => _value; [MemberNotNullWhen(true, nameof(HasValue), nameof(_value))] public bool HasValue {get;init;} public static Option Some(T value) => new Option(value, true); // public bool Equals(Option other) // { // return other.HasValue == HasValue && EqualityComparer.Default.Equals(_value,other._value); // } public TResult Match(Func onSome, Func onNone) => HasValue ? onSome(_value) : onNone(); // public TOption Map(Func f) where TOption : IOption => HasValue ? TOption.Some(f(Value)) : TOption.None; // public Option Map(Func f) => HasValue ? Option.Some(f(Value)) : Option.None; public Option Map(Func f) => HasValue ? Option.Some(f(_value)) : Option.None; public Option Bind(Func> f) => HasValue ? f(_value) : Option.None; public static implicit operator Option (T? nullable) => nullable is not null?Some(nullable) : None; public static implicit operator T? (Option nullable) => nullable.Value; // public static implicit operator bool(Option option) => option.HasValue; public static bool operator true(Option value) => value.HasValue; public static bool operator false(Option value) => !value.HasValue; public override int GetHashCode()=> HasValue? _value.GetHashCode() : 0; public override string ToString() => HasValue ? $"Some({_value})" : $"None<{typeof(T).Name}>()"; // public override bool Equals([NotNullWhen(true)] object? obj) => obj is Option option?Equals(option):false; // public T Or(Func aDefault) => HasValue?_value:aDefault(); // public T OrDefault(T aDefault) => HasValue?_value:aDefault; // IOption IOption.Map(Func f) => Match>(onSome => Some.Of(f(onSome)), ()=>None.Of); // public bool TryGetValue(out T value) // { // if (HasValue) // { // value = Value; // return true; // } // value = default; // return false; // } }