Created
October 25, 2016 00:54
-
-
Save AlbertoMonteiro/6aa46940d431ef8ff187723ac734853a to your computer and use it in GitHub Desktop.
Discriminated Unions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using static EspecialTry.Helpers; | |
namespace EspecialTry | |
{ | |
public class Try<TFailure, TSuccess> | |
{ | |
internal TFailure Failure { get; } | |
internal TSuccess Success { get; } | |
public bool IsFailure { get; } | |
public bool IsSucess => !IsFailure; | |
internal Try(TFailure failure) | |
{ | |
IsFailure = true; | |
Failure = failure; | |
Success = default(TSuccess); | |
} | |
internal Try(TSuccess success) | |
{ | |
IsFailure = false; | |
Failure = default(TFailure); | |
Success = success; | |
} | |
public static implicit operator Try<TFailure, TSuccess>(TFailure failure) | |
=> new Try<TFailure, TSuccess>(failure); | |
public static implicit operator Try<TFailure, TSuccess>(TSuccess success) | |
=> new Try<TFailure, TSuccess>(success); | |
public TResult Match<TResult>(Func<TFailure, TResult> failure, Func<TSuccess, TResult> success) => IsFailure ? failure(Failure) : success(Success); | |
public Unit Match(Action<TFailure> failure, Action<TSuccess> success) | |
=> Match(ToFunc(failure), ToFunc(success)); | |
public Try<TFailure, TResult> Match<TResult>(Action<TFailure> failure, Func<TSuccess, TResult> success) | |
=> IsFailure ? new Try<TFailure, TResult>(Failure) : success(Success); | |
public Try<TFailure, TResult> Match<TResult>(Action<TFailure> failure, Func<TSuccess, Try<TFailure, TResult>> success) | |
=> IsFailure ? new Try<TFailure, TResult>(Failure) : success(Success); | |
} | |
public struct Unit | |
{ } | |
public static partial class Helpers | |
{ | |
private static readonly Unit unit = new Unit(); | |
public static Unit Unit() => unit; | |
public static Func<T, Unit> ToFunc<T>(Action<T> action) => o => | |
{ | |
action(o); | |
return Unit(); | |
}; | |
public static Try<Exception, T> AsTry<T>(this T exception) | |
=> new Try<Exception, T>(exception); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using static System.Console; | |
namespace EspecialTry | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Divide(4, 2) | |
.Match(failure: e => WriteLine(e.Message), | |
success: MultiplicaPorDez) | |
.Match(failure: e => WriteLine(e.Message), | |
success: value => value + 1) | |
.Match(failure: e => WriteLine(e.Message), | |
success: WriteLine); | |
Divide(4, 0) | |
.Match(failure: e => WriteLine(e.Message), | |
success: MultiplicaPorDez) | |
.Match(failure: e => WriteLine(e.Message), | |
success: value => WriteLine(value)); | |
Divide(4, 1) | |
.Match(failure: e => WriteLine(e.Message), | |
success: value => | |
{ | |
if (value == 4) | |
return new Exception("Hi"); | |
return 1.AsTry(); | |
}) | |
.Match(failure: e => WriteLine(e.Message), | |
success: value => WriteLine(value)); | |
} | |
private static double MultiplicaPorDez(double value) | |
=> value * 10; | |
public static Try<Exception, double> Divide(double a, double b) | |
{ | |
if (Math.Abs(b) < 0.0001) return new DivideByZeroException(); | |
return a / b; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment