128 lines
3.2 KiB
C#
128 lines
3.2 KiB
C#
using System;
|
|
|
|
namespace KitsuneCafe.System
|
|
{
|
|
public class Option
|
|
{
|
|
public static IOption<T> Some<T>(T value) => IOption<T>.Some(value);
|
|
public static IOption<T> None<T>() => IOption<T>.None();
|
|
}
|
|
|
|
public interface IOption<T>
|
|
{
|
|
private static IOption<T> none = new None<T>();
|
|
|
|
public abstract bool IsSome { get; }
|
|
|
|
public static IOption<T> Some(T value) => new Some<T>(value);
|
|
public static IOption<T> None() => none;
|
|
|
|
public abstract T Unwrap();
|
|
|
|
public abstract IOption<TResult> SelectMany<TResult>(Func<T, IOption<TResult>> func);
|
|
public abstract IOption<TResult> Select<TResult>(Func<T, TResult> func);
|
|
public abstract IOption<T> Where(Func<T, bool> predicate);
|
|
public abstract TResult Match<TResult>(Func<T, TResult> ifSome, Func<TResult> ifNone);
|
|
public abstract T UnwrapOrDefault(T defaultValue = default);
|
|
public abstract T UnwrapOrElse(Func<T> func);
|
|
|
|
public virtual IOption<T> Do(Action<T> func)
|
|
{
|
|
if (IsSome) { func(Unwrap()); }
|
|
return this;
|
|
}
|
|
}
|
|
|
|
public readonly struct Some<T> : IOption<T>
|
|
{
|
|
private readonly T value;
|
|
|
|
public readonly bool IsSome => true;
|
|
|
|
internal Some(T value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
public IOption<TResult> SelectMany<TResult>(Func<T, IOption<TResult>> func)
|
|
{
|
|
return func(value);
|
|
}
|
|
|
|
public T Unwrap()
|
|
{
|
|
return value;
|
|
}
|
|
|
|
public IOption<TResult> Select<TResult>(Func<T, TResult> func)
|
|
{
|
|
return IOption<TResult>.Some(func(value));
|
|
}
|
|
|
|
public IOption<T> Where(Func<T, bool> predicate)
|
|
{
|
|
if (predicate(value))
|
|
{
|
|
return this;
|
|
}
|
|
|
|
return IOption<T>.None();
|
|
}
|
|
|
|
public TResult Match<TResult>(Func<T, TResult> ifSome, Func<TResult> ifNone)
|
|
{
|
|
return ifSome(value);
|
|
}
|
|
|
|
public T UnwrapOrDefault(T defaultValue = default)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
public T UnwrapOrElse(Func<T> _func)
|
|
{
|
|
return value;
|
|
}
|
|
}
|
|
|
|
public readonly struct None<T> : IOption<T>
|
|
{
|
|
public readonly bool IsSome => false;
|
|
|
|
public IOption<TResult> SelectMany<TResult>(Func<T, IOption<TResult>> func)
|
|
{
|
|
return IOption<TResult>.None();
|
|
}
|
|
|
|
public T Unwrap()
|
|
{
|
|
throw new InvalidOperationException("Attempted to unwrap value of None.");
|
|
}
|
|
|
|
public IOption<TResult> Select<TResult>(Func<T, TResult> func)
|
|
{
|
|
return IOption<TResult>.None();
|
|
}
|
|
|
|
public IOption<T> Where(Func<T, bool> predicate)
|
|
{
|
|
return IOption<T>.None();
|
|
}
|
|
|
|
public TResult Match<TResult>(Func<T, TResult> ifSome, Func<TResult> ifNone)
|
|
{
|
|
return ifNone();
|
|
}
|
|
|
|
public T UnwrapOrDefault(T defaultValue = default)
|
|
{
|
|
return defaultValue;
|
|
}
|
|
|
|
public T UnwrapOrElse(Func<T> func)
|
|
{
|
|
return func();
|
|
}
|
|
}
|
|
}
|
|
|