public static Subsystem <B> Bind <A, B>(this Subsystem <A> ma, Func <A, Subsystem <B> > f) => () => { try { // Run ma var outA = ma(); if (outA.IsFailed) { // If running ma failed then early out return(Out <B> .FromError((Error)outA.Error, outA.Output)); } else { // Run the bind function to get the mb monad var mb = f(outA.Value); // Run the mb monad var outB = mb(); // Concatenate the output from running ma and mb var output = outA.Output + Seq1(outA.Value.ToString()) + outB.Output + Seq1(outB.Value.ToString()); // Return our result return(outB.IsFailed ? Out <B> .FromError((Error)outB.Error, output) : Out <B> .FromValue(outB.Value, output)); } } catch (Exception e) { // Capture exceptions return(Out <B> .FromException(e)); } };
public static Subsystem <A> Fail <A>(Exception exception) => () => Out <A> .FromException(exception);