Overload for Option.Unwrap that takes a function
guythetechie opened this issue · 4 comments
Let's say we have the following situation:
// Get parent's favorite child, returning None if they lied about being neutral :)
Maybe<Child> GetFavoriteChild(Parent parent) => ...
// Expensive computation to predict a likely favorite
Child PredictFavoriteChild() => ...
// Option 1
Child WhoGetsTheLastCookie(Parent parent)
{
var defaultChild = PredictFavoriteChild(); // Expensive computation is always performed
return GetFavoriteChild(parent).Unwrap(defaultChild );
}
// Option 2 - currently works just fine, just not as clean as Option 3 (IMO)
Child WhoGetsTheLastCookie(Parent parent)
{
var childOption = GetFavoriteChild(customer);
return childOption .HasValue ? childOption .Value : PredictFavoriteChild();
}
// Option 3 - proposed Unwrap overload
Child WhoGetsTheLastCookie(Parent parent) =>
GetFavoriteChild(customer)
.Unwrap(PredictFavoriteChild);
In F#, there is a defaultWith function that looks like this:
Option.defaultWith : (unit -> 'T) -> ('T option): 'T
I believe this could fit well as an Unwrap overload:
// Proposed new overload
public static T Unwrap<T>(this Maybe<T> maybe, Func<T> compensator)
// Existing Unwrap definitions for reference
public static T Unwrap<T>(this Maybe<T> maybe, T defaultValue = default(T))
public static K Unwrap<T, K>(this Maybe<T> maybe, Func<T, K> selector, K defaultValue = default(K))
I would find value in adding this overload, but was wondering whether it's generally useful enough to add to the library. Happy to create a PR if necessary.
Thanks!
Thanks for the info. I do see a difference between my proposal and the discussion. In the discussion, GetValueOrDefault
would take a default value as a parameter: GetValueOrDefault<T>(T default)
. I propose that it also takes a function returning a default value: GetValueOrDefault<T>(Func<T> selector)
.
Happy to close this and fold it into the existing thread.
Yeah, I think this overload would be useful, and maybe GetValueOrDefault<T>(Func<Task<T>> selector)
as well. Feel free to add a suggestion to that issue.
I also agree. GetValueOrDefault<T>(Func<Task<T>> selector)
is a nice addition.