Init Scripts in new repo
This commit is contained in:
40
Functional/OptionalStruct.cs
Normal file
40
Functional/OptionalStruct.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace SJK.Functional;
|
||||
|
||||
public struct Option<T> : IEquatable<Option<T>>
|
||||
{
|
||||
private readonly T? _value;
|
||||
[MemberNotNullWhen(true, nameof(_value))]
|
||||
public bool HasValue { get; }
|
||||
public static Option<T> None => new(default, false);
|
||||
public static Option<T> Some(T value) => new(value, true);
|
||||
private Option(T? value, bool hasValue)
|
||||
{
|
||||
Debug.Assert(!(value is null && hasValue), "Can not create an option with a null value had say it has one");
|
||||
|
||||
_value = value;
|
||||
HasValue = hasValue;
|
||||
}
|
||||
public T? Value => HasValue ? _value : throw new InvalidOperationException("Can not retrive value when there is no value.");
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TResult Match<TResult>(Func<T, TResult> some, Func<TResult> none) => HasValue ? some(_value) : none();
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Option<TResult> Map<TResult>(Func<T, TResult> f) => HasValue ? Option<TResult>.Some(f(_value)) : Option<TResult>.None;
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Option<TResult> Bind<TResult>(Func<T, Option<TResult>> f) => HasValue ? f(_value) : Option<TResult>.None;
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public T OrDefault(T value) => HasValue ? _value : value;
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public T Or(Func<T> factory) => HasValue ? _value : factory();
|
||||
|
||||
public override bool Equals([NotNullWhen(true)] object? obj) => obj is Option<T> other && Equals(other);
|
||||
|
||||
public bool Equals(Option<T> other) => (HasValue == other.HasValue) && (!HasValue || EqualityComparer<T>.Default.Equals(_value, other._value));
|
||||
|
||||
public override int GetHashCode() => HasValue ? EqualityComparer<T>.Default.GetHashCode(_value) : 0;
|
||||
public override string ToString() => HasValue ? $"Some({_value})" : $"None<{typeof(T).Name}>()";
|
||||
}
|
||||
Reference in New Issue
Block a user