Way I could do this in C#. Tried doing something like this myself, but it didn’t work out.
public abstract class Maybe<T>
{
public abstract T Value { get; }
public virtual string Failure => null;
public SelectMany<U, V>(Func<T, Maybe<U>> f, Func<T, U, V> g)
{
var that = f(this.Value);
if(that.Failure != null)
return new Failed(that.Failure);
return new Success(g(this.Value, that.Value));
}
public sealed class Success : Maybe<T>
{
public override Value { get; }
public Success(T value) => this.Value = value;
}
public sealed class Failed : Maybe<T>
{
public override Failure { get; }
public override Value => throw new InvalidOperationException();
public Failed(string s) => this.Failure = s;
}
}
Maybe<string> UpdateCustomerWithErrorHandling()
{
return
from req in receiveRequest();
from v in validateRequest(req)
from c in canicalizeEmail(req)
from d in db.updateDbFromRequest(req)
from e in smptServer.sendEmail(req.Email)
select "OK";
}Valid C#: https://gist.github.com/noblethrasher/2d0e99f86b9853c646f3fa...