136 lines
4.3 KiB
C#
136 lines
4.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace KitsuneCafe.Sys
|
|
{
|
|
public class Option
|
|
{
|
|
public static IOption<T> Some<T>(T value) => new Some<T>(value);
|
|
public static IOption<T> None<T>() => new None<T>();
|
|
}
|
|
|
|
public interface IOption<T> : IEnumerable<T>
|
|
{
|
|
IOption<U> And<U>(IOption<U> optb);
|
|
IOption<U> AndThen<U>(Func<T, IOption<U>> fn);
|
|
IOption<T> Filter(Predicate<T> predicate);
|
|
|
|
bool IsSome();
|
|
bool IsNone();
|
|
|
|
IOption<U> Map<U>(Func<T, U> transform);
|
|
U MapOr<U>(U defaultValue, Func<T, U> transform);
|
|
U MapOrDefault<U>(Func<T, U> transform);
|
|
U MapOrElse<U>(Func<U> defaultFn, Func<T, U> transform);
|
|
|
|
IResult<T, E> OkOr<E>(E err);
|
|
IResult<T, E> OkOrElse<E>(Func<E> err);
|
|
|
|
IOption<T> Or(IOption<T> optb);
|
|
IOption<T> OrElse(Func<IOption<T>> optb);
|
|
IOption<T> Xor(IOption<T> optb);
|
|
|
|
T Unwrap();
|
|
T UnwrapOr(T defaultValue);
|
|
|
|
T UnwrapOrDefault();
|
|
T UnwrapOrElse(Func<T> defaultValue);
|
|
}
|
|
|
|
public static class Option<T>
|
|
{
|
|
public static Some<T> Some(T value) => new(value);
|
|
public static readonly None<T> None = new();
|
|
}
|
|
|
|
public readonly struct Some<T> : IOption<T>
|
|
{
|
|
private readonly T value;
|
|
|
|
public Some(T value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
public IOption<U> And<U>(IOption<U> optb) => optb;
|
|
public IOption<U> AndThen<U>(Func<T, IOption<U>> fn) => fn(value);
|
|
|
|
public IOption<T> Filter(Predicate<T> predicate)
|
|
{
|
|
return predicate(value) ? this : Option<T>.None;
|
|
}
|
|
|
|
public bool IsSome() => true;
|
|
public bool IsNone() => false;
|
|
|
|
public IOption<U> Map<U>(Func<T, U> transform) => new Some<U>(transform(value));
|
|
public U MapOr<U>(U defaultValue, Func<T, U> transform) => transform(value);
|
|
public U MapOrDefault<U>(Func<T, U> transform) => transform(value);
|
|
public U MapOrElse<U>(Func<U> defaultFn, Func<T, U> transform) => transform(value);
|
|
|
|
public IResult<T, E> OkOr<E>(E err) => new Ok<T, E>(value);
|
|
public IResult<T, E> OkOrElse<E>(Func<E> err) => new Ok<T, E>(value);
|
|
|
|
public IOption<T> Or(IOption<T> optb) => this;
|
|
public IOption<T> OrElse(Func<IOption<T>> optb) => this;
|
|
|
|
public IOption<T> Xor(IOption<T> optb)
|
|
{
|
|
return optb.IsNone() ? this : Option<T>.None;
|
|
}
|
|
public T Unwrap() => value;
|
|
public T UnwrapOr(T defaultValue) => value;
|
|
public T UnwrapOrDefault() => value;
|
|
public T UnwrapOrElse(Func<T> defaultValue) => value;
|
|
|
|
public IEnumerator<T> GetEnumerator()
|
|
{
|
|
yield return value;
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
}
|
|
|
|
public readonly struct None<T> : IOption<T>
|
|
{
|
|
public IOption<U> And<U>(IOption<U> optb) => Option<U>.None;
|
|
public IOption<U> AndThen<U>(Func<T, IOption<U>> fn) => Option<U>.None;
|
|
public IOption<T> Filter(Predicate<T> predicate) => this;
|
|
|
|
public bool IsSome() => false;
|
|
public bool IsNone() => true;
|
|
|
|
public IOption<U> Map<U>(Func<T, U> transform) => Option<U>.None;
|
|
public U MapOr<U>(U defaultValue, Func<T, U> transform) => defaultValue;
|
|
public U MapOrDefault<U>(Func<T, U> transform) => default;
|
|
public U MapOrElse<U>(Func<U> defaultFn, Func<T, U> transform) => defaultFn();
|
|
|
|
public IResult<T, E> OkOr<E>(E err) => new Err<T, E>(err);
|
|
public IResult<T, E> OkOrElse<E>(Func<E> err) => new Err<T, E>(err());
|
|
|
|
public IOption<T> Or(IOption<T> optb) => optb;
|
|
public IOption<T> OrElse(Func<IOption<T>> optb) => optb();
|
|
public IOption<T> Xor(IOption<T> optb)
|
|
{
|
|
return optb.IsNone() ? this : Option<T>.None;
|
|
}
|
|
public T Unwrap()
|
|
{
|
|
throw new NullReferenceException();
|
|
}
|
|
|
|
public T UnwrapOr(T defaultValue) => defaultValue;
|
|
|
|
public T UnwrapOrDefault() => default;
|
|
public T UnwrapOrElse(Func<T> defaultValue) => defaultValue();
|
|
|
|
public IEnumerator<T> GetEnumerator()
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
}
|
|
}
|
|
|