104 lines
4.6 KiB
C#
104 lines
4.6 KiB
C#
// using System.Diagnostics;
|
|
// using System.Diagnostics.CodeAnalysis;
|
|
// using System.Runtime.CompilerServices;
|
|
// using SJK.Functional;
|
|
|
|
// namespace SJK.Functional
|
|
// {
|
|
// /// <summary>
|
|
// /// A simple implementation of a monadic option, which can hold either a value of type T or no value.
|
|
// /// </summary>
|
|
// 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);
|
|
|
|
// /// <summary>
|
|
// /// A constructor for creating an instance of the Option struct.
|
|
// /// </summary>
|
|
// 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;
|
|
// }
|
|
|
|
// /// <summary>
|
|
// /// Gets the held value if it exists. Throws an exception if there's no value.
|
|
// /// </summary>
|
|
// public T? Value => HasValue ? _value : throw new InvalidOperationException("Can not retrieve value when there is no value.");
|
|
|
|
// /// <summary>
|
|
// /// Applies a function to the held value if it exists, otherwise applies another function.
|
|
// /// </summary>
|
|
// /// <typeparam name="TResult">The type of result produced by the functions.</typeparam>
|
|
// public TResult Match<TResult>(Func<T, TResult> some, Func<TResult> none)
|
|
// {
|
|
// // If we have a value, apply 'some' to it. Otherwise, apply 'none'.
|
|
// return HasValue ? some(_value) : none();
|
|
// }
|
|
|
|
// /// <summary>
|
|
// /// Maps the held value if it exists using the given function, otherwise returns an empty option.
|
|
// /// </summary>
|
|
// /// <typeparam name="TResult">The type of result produced by the mapping function.</typeparam>
|
|
// public Option<TResult> Map<TResult>(Func<T, TResult> f)
|
|
// {
|
|
// // If we have a value, map it and wrap the result in another option. Otherwise, return an empty option.
|
|
// return HasValue ? Option<TResult>.Some(f(_value)) : Option<TResult>.None;
|
|
// }
|
|
|
|
// /// <summary>
|
|
// /// Binds the held value if it exists using the given function, otherwise returns an empty option.
|
|
// /// </summary>
|
|
// /// <typeparam name="TResult">The type of result produced by the binding function.</typeparam>
|
|
// public Option<TResult> Bind<TResult>(Func<T, Option<TResult>> f)
|
|
// {
|
|
// // If we have a value, bind it and wrap the result in another option. Otherwise, return an empty option.
|
|
// return HasValue ? f(_value) : Option<TResult>.None;
|
|
// }
|
|
|
|
// /// <summary>
|
|
// /// Returns the held value if it exists, otherwise returns a default value.
|
|
// /// </summary>
|
|
// public T OrDefault(T value)
|
|
// {
|
|
// // If we have a value, return it. Otherwise, return the default value.
|
|
// return HasValue ? _value : value;
|
|
// }
|
|
|
|
// /// <summary>
|
|
// /// Returns the held value if it exists, otherwise returns a result from a factory function.
|
|
// /// </summary>
|
|
// public T Or(Func<T> factory)
|
|
// {
|
|
// // If we have a value, return it. Otherwise, invoke the factory function and return its result.
|
|
// return HasValue ? _value : factory();
|
|
// }
|
|
// public override bool Equals([NotNullWhen(true)] object? obj) => obj is Option<T> other && Equals(other);
|
|
|
|
// /// <summary>
|
|
// /// Checks for equality with another option of type T.
|
|
// /// </summary>
|
|
// public bool Equals(Option<T> other)
|
|
// {
|
|
// // If both options have values, check their equality. Otherwise, consider them equal if they're both empty.
|
|
// return (HasValue == other.HasValue) && (!HasValue || EqualityComparer<T>.Default.Equals(_value, other._value));
|
|
// }
|
|
|
|
// public override int GetHashCode() => HasValue ? EqualityComparer<T>.Default.GetHashCode(_value) : 0;
|
|
|
|
// /// <summary>
|
|
// /// Returns a string representation of this option.
|
|
// /// </summary>
|
|
// public override string ToString()
|
|
// {
|
|
// // If we have a value, return it as a 'Some' with the value. Otherwise, return an empty 'None'.
|
|
// return HasValue ? $"Some({_value})" : $"None<{typeof(T).Name}>()";
|
|
// }
|
|
// }
|
|
// } |