Translate

miércoles, 31 de diciembre de 2025

Métodos Monádicos en C# parte 2



Podemos crear nuestra propia clase monádica, similar a std::expected o Result de Rust:


public abstract class Result<T>

{

    public abstract Result<U> Map<U>(Func<T, U> f);

    public abstract Result<U> FlatMap<U>(Func<T, Result<U>> f);

    public abstract T OrElse(T fallback);

    public static Result<T> Ok(T value) => new OkResult<T>(value);

    public static Result<T> Error(string message) => new ErrorResult<T>(message);

}


public class OkResult<T> : Result<T>

{

    private readonly T value;

    public OkResult(T v) => value = v;

    public override Result<U> Map<U>(Func<T, U> f) => Result<U>.Ok(f(value));

    public override Result<U> FlatMap<U>(Func<T, Result<U>> f) => f(value);

    public override T OrElse(T fallback) => value;

}


public class ErrorResult<T> : Result<T>

{

    private readonly string message;

    public ErrorResult(string msg) => message = msg;

    public override Result<U> Map<U>(Func<T, U> f) => Result<U>.Error(message);

    public override Result<U> FlatMap<U>(Func<T, Result<U>> f) => Result<U>.Error(message);

    public override T OrElse(T fallback) => fallback;

}


Uso:


Result<int> parse(string s) => int.TryParse(s, out var n) ? Result<int>.Ok(n) : Result<int>.Error("Invalid");

var r = parse("42")

    .FlatMap(x => Result<int>.Ok(x * 2))

    .Map(x => x + 1)

    .OrElse(0);

Console.WriteLine(r); // 85


Los métodos monádicos permiten escribir código más expresivo y seguro en C#, eliminando condicionales repetitivos y manejo manual de errores.