using Mammoth.Couscous.java.util.function; namespace Mammoth.Couscous.java.util { internal interface Optional { bool isPresent(); Optional map(Function function); Optional flatMap(Function> function); Optional filter(Predicate predicate); T orElse(T value); T orElseGet(Supplier supplier); T orElseThrow(Supplier exceptionSupplier) where TException : System.Exception; T get(); void ifPresent(Consumer consumer); } internal interface None { } internal struct None : None, Optional { internal static readonly None Instance = new None(); public override bool Equals(object other) { return other is None; } public override int GetHashCode() { return 0; } public bool isPresent() { return false; } public Optional map(Function function) { return new None(); } public Optional flatMap(Function> function) { return new None(); } public Optional filter(Predicate predicate) { return this; } public T orElse(T value) { return value; } public T orElseGet(Supplier supplier) { return supplier.get(); } public T orElseThrow(Supplier exceptionSupplier) where TException : System.Exception { throw exceptionSupplier.get(); } public T get() { throw new NoSuchElementException(); } public void ifPresent(Consumer consumer) { } } internal interface Some { object getObject(); } internal struct Some : Some, Optional { private readonly T _value; internal Some(T value) { _value = value; } public override bool Equals(object other) { var otherSome = other as Some; if (otherSome == null) { return false; } else { return _value.Equals(otherSome.getObject()); } } public override int GetHashCode() { return _value.GetHashCode(); } public bool isPresent() { return true; } public Optional map(Function function) { return new Some(function.apply(_value)); } public Optional flatMap(Function> function) { return function.apply(_value); } public Optional filter(Predicate predicate) { if (predicate.test(_value)) { return this; } else { return None.Instance; } } public T orElse(T value) { return _value; } public T orElseGet(Supplier supplier) { return _value; } public T orElseThrow(Supplier exceptionSupplier) where TException : System.Exception { return _value; } public T get() { return _value; } public object getObject() { return _value; } public void ifPresent(Consumer consumer) { consumer.accept(_value); } } internal static class Optional { internal static Optional empty() { return None.Instance; } internal static Optional of(T value) { return new Some (value); } } }