Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace current Result<T>.Match syntax #1141

Open
Hulkstance opened this issue Nov 10, 2022 · 2 comments
Open

Replace current Result<T>.Match syntax #1141

Hulkstance opened this issue Nov 10, 2022 · 2 comments

Comments

@Hulkstance
Copy link

Hulkstance commented Nov 10, 2022

Why not create something like the following? Your current Result<T>.Match / IfSucc syntax looks a bit weird and so is the name IfSucc.

if (result.IsSuccess)
{
    var data = result.Data; // compiler won't comply for nullability issues because it was successful
}

if (result.IsFaulted)
{
    var error = result.Error; // compiler won't comply for nullability issues because it was faulted
}

instead of

 _ = result.IfSucc(data =>
{
    // that way I could access the data but it ain't as pretty as the one above.
});

I assume the reason you didn't is because you were not aware of the MemberNotNullWhen/NotNullWhen attributes.

public sealed record CallResult<T>(
    [property: MemberNotNullWhen(true, nameof(CallResult<T>.Data))]
    [property: MemberNotNullWhen(false, nameof(CallResult<T>.Error))]
    bool Success, T? Data, Error? Error)
{
    public CallResult(T data) : this(true, data, default)
    {
    }

    public CallResult(Error error) : this(false, null, error)
    {
    }
}

public abstract record Error(int? Code, string Message, object? Data);
@MrWuffels
Copy link

MrWuffels commented Feb 28, 2023

Even tho this post is a bit older, I'm gonna answer it out of my knowledge for anyone reading this and asking this himself, too.

  1. Result<> isn't a fully implemented monad in this library, it is just a pure return value of the Try<>-monad. The Try-monad is supposed to be matched directly instead of invoking it.

  2. MemberNotNullWhen-Attribute got introduced in .NET 5. LanguageExt is netstandard 2.0. Additionally the Try<> and Result<> monads are way older and got more or less replaced since introduction of the Eff<> and Aff<> monads

  3. Even when you using those attributes: If you use it that way you are reintroducing problems we're happy to got rid of the functional way: You are generating boilerplate code and therefor lot of code noise just to check safe access for properties, and the possibility of an unsafe access is back again. And if the possibility of unsafe access is there, sooner or later there WILL be an unsafe access.

When you use monads you rather want to produce so called railroaded code: Stay in the monads by using map and bind functions, lift pure values up to them and keep this up until you reach the end of the application. Monads aren't supposed to be unwrapped after every operation

@louthy
Copy link
Owner

louthy commented Feb 28, 2023

@MrWuffels You've got the job ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants