Skip to content

Instantly share code, notes, and snippets.

@aalmada
Created March 11, 2020 10:41
Show Gist options
  • Save aalmada/3860626793a1aa1ef34f5ed64a78ae7f to your computer and use it in GitHub Desktop.
Save aalmada/3860626793a1aa1ef34f5ed64a78ae7f to your computer and use it in GitHub Desktop.
using System;
using System.Diagnostics.Contracts;
namespace NetFabric.Hyperlinq
{
public static class Result
{
[Pure]
public static DelayedOk<TOk> Ok<TOk>(TOk ok)
=> new DelayedOk<TOk>(ok);
[Pure]
public static DelayedError<TError> Error<TError>(TError error)
=> new DelayedError<TError>(error);
}
public readonly struct Result<TOk, TError>
{
readonly bool isError;
readonly TOk ok;
readonly TError error;
Result(bool isError, TOk ok, TError error)
{
this.error = error;
this.isError = isError;
this.ok = ok;
}
public Result(TOk ok)
: this (false, ok, default)
{
}
public Result(TError error)
: this (true, default, error)
{
}
public static implicit operator Result<TOk, TError>(DelayedOk<TOk> ok) =>
new Result<TOk, TError>(ok.Value);
public static implicit operator Result<TOk, TError>(DelayedError<TError> error) =>
new Result<TOk, TError>(error.Value);
public void Deconstruct(out bool isError, out TOk ok, out TError error)
{
isError = this.isError;
ok = this.ok;
error = this.error;
}
[Pure]
public TOut Match<TOut>(Func<TOk, TOut> ok, Func<TError, TOut> error)
=> isError ? error(this.error) : ok(this.ok);
public void Match(Action<TOk> ok, Action<TError> error)
{
if (isError)
error(this.error);
else
ok(this.ok);
}
[Pure]
public Result<TOkOut, TErrorOut> Select<TOkOut, TErrorOut>(Selector<TOk, TOkOut> ok, Selector<TError, TErrorOut> error)
=> isError ? new Result<TOkOut, TErrorOut>(error(this.error)) : new Result<TOkOut, TErrorOut>(ok(this.ok));
[Pure]
public Result<TOkOut, TErrorOut> Bind<TOkOut, TErrorOut>(Func<TOk, TError, Result<TOkOut, TErrorOut>> bind)
=> bind(ok, error);
}
public readonly struct DelayedOk<T>
{
public T Value { get; }
public DelayedOk(T value)
=> Value = value;
}
public readonly struct DelayedError<T>
{
public T Value { get; }
public DelayedError(T value)
=> Value = value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment