Files
SjkScripts/Functional/Option.cs
ronnie 6ba5d248f8
All checks were successful
Build NuGet / build (push) Successful in 40s
Added HasValue and ifSome/None, and Member not null; for Option.Value
2026-08-07 13:12:31 -04:00

69 lines
2.7 KiB
C#

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