Result to Maybe
Hi Vladimir, thanks for that great library and your premium stuff on Pluralsight. I was wondering why there is no Extension on Result<T> to convert it to a Maybe<T> like the following:
public static class ResultToMaybeExtensions { public static Maybe<T> ToMaybe<T>(this Result<T> result) { return result.IsFailure ? Maybe<T>.None : Maybe.From(result.Value); } }
Do I misunderstande these two concepts so that this is not a valid use case? For example I would like to offer the value object Address on an Entity Customer as a get-only Maybe. Therefore I would use Address.Create(...) and later in the process I need to transform it to a Maybe monade.
That's a good question. I don't think it's a good idea to have such an extension method because it leads to the loss of information during the conversion -- the error that caused the failure is now lost. Generally, you want your code to explicitly check for errors in the result, you don't want it to silently convert to a Maybe.
If you do want to omit the information about the error, then you can use GetValueOrDefault. This method acts similarly to ToMaybe and you are being explicit that do don't need to error info. This code should compile as-is (though I didn't check):
Result<User> result = ParseUser();
Maybe<User> user = result.GetValueOrDefault();
Okay, so I use this way. The scenario was the following: You have an Entity and you perform a business action. Within this method we try to create a Value Object. If the creation produces errors, the business action returns an error result. If not, it returns success. But: The Entity has a property of that Value Object, e.g. Address. And I want to tell the consumers: Hey, Address is maybe not there. For most scenarios we built dedicated NULL-Objects, e.g. NoAddress.Instance. But with EF Core this is always annoying, so there are cases when I say: Maybe instead of an NULL-Object is a easier way.
Yeah, these are two different scenarios. You are right to model the first one as a Result and the second one as Maybe. The conversion between them using the explicit result.GetValueOrDefault() seems to be the most appropriate.
Thanks Vladimir for explanation. :+1: I would really enjoy seeing your Pluralsight course EF Core Encapsulation updated to the new possibilities of EF Core 6. :v: Maybe I can contribute to or support you with Code Samples
Hey Vladimir,
as @hankovich already mentioned in #358 , the .GetValueOrDefault() method is currently available only for Maybe. Do you plan to implement this method on Result as well?
Thank you for your answer in advance.
Yes, it is planned, just didn't have time yet to implement it. Feel free to submit a PR.
I'd like to chime in that I still feel that a ToMaybe extension is still needed.
- The
.GetValueOrDefault()is only onResult<T>, and not onResult<T,E>. - It should be up to the developer to decide when they want to throw away information.
.GetValueOrDefault()requires a cast which means you have to explicitly add type information. This may be fine when creating a variable (though I still would prefervar), but becomes awkward in a LINQ query.- Maybe already has a LINQ extension method for
Choose. - Returning null causes extra warnings when nullable reference types are enabled.
public override IEnumerable<AimNumber> Shrink(AimNumber type)
{
var aimString = AimNumber.AsString(type);
return Arb.Shrink(aimString)
.Select(AimNumber.FromString)
// IDE complains about r being nullable and a type mismatch to the method return signature
.Select(r => (Maybe<AimNumber>)r.GetValueOrDefault())
.Choose();
}
return Arb.Shrink(aimString)
.Select(AimNumber.FromString)
.Select(r => r.ToMaybe()) // No IDE complaints, more concise and clear
.Choose();
I agree, we can put ToMaybe in.
For reference: I've tried to follow my past reasoning, but it doesn't quite make sense to me now. What I was arguing against is implicit conversion from Result to Maybe, as in:
Result<Email> result = Email.Create(request.Email);
Maybe<Email> maybe = result; // Implicit conversion
That would be a bad idea. But with a method call (be it GetValueOrDefault or ToMaybe) we don't really do an implicit conversion, but an explicit one. Here's more on this topic: https://khorikov.org/posts/2021-11-08-converting-result-to-maybe/
Please feel free to submit a PR.