CSharpFunctionalExtensions icon indicating copy to clipboard operation
CSharpFunctionalExtensions copied to clipboard

Add Func<> equivalent to Execute Action<> Maybe extension

Open laurence79 opened this issue 7 years ago • 9 comments

Great library, love the approach and your Enterprise Craftsmanship series 😊

When using the library in my own project I found that I sometimes wanted to return a value from the Maybe<>.Execute() extension method, so I've added a Func<> overload in this PR in the hope that it might be of use to others.

laurence79 avatar Sep 13 '16 15:09 laurence79

Alternatively, the following is more comprehensive but extends Nullable<<T>> as well. I didn't know if you wanted to go that far...

public static Maybe<TOut> Execute<TIn, TOut>(this Maybe<TIn> maybe, Func<TIn, TOut> func)
    where TIn:class
    where TOut:class
{
    if (maybe.HasValue)
        return func(maybe.Value);
    else
        return null;
}

public static TOut? Execute<TIn, TOut>(this Maybe<TIn> maybe, Func<TIn, TOut?> func)
    where TIn : class
    where TOut : struct
{
    if (maybe.HasValue)
        return func(maybe.Value);
    else
        return null;
}

public static Maybe<TOut> Execute<TIn, TOut>(this TIn? nullable, Func<TIn, TOut> func)
    where TIn : struct
    where TOut : class
{
    if (nullable.HasValue)
        return func(nullable.Value);
    else
        return null;
}

public static TOut? Execute<TIn, TOut>(this TIn? nullable, Func<TIn, TOut?> func)
    where TIn : struct
    where TOut : struct
{
    if (nullable.HasValue)
        return func(nullable.Value);
    else
        return null;
}

laurence79 avatar Sep 13 '16 15:09 laurence79

Thanks for the contribution!

Did you consider the Select extension method? It seems like it does exactly what you need (transforms a Maybe<T1> to a Maybe<T2>).

I see now that the naming I've chosen is probably confusing. Do you think both Execute and Select should be named the same way? If so, which name should we pick?

Regarding extensions for structs - I like the idea!

vkhorikov avatar Sep 13 '16 15:09 vkhorikov

I did completely miss that 😞 I was looking for something similar to OnSuccess() for Result<>. I think Select is the logical choice, I'll work with that for now.

laurence79 avatar Sep 13 '16 16:09 laurence79

Still great suggestion regarding structs! I'll add it soon and will roll out a new version of the lib.

vkhorikov avatar Sep 13 '16 17:09 vkhorikov

As overloads to Select? I'm happy to amend the PR if that helps?

laurence79 avatar Sep 13 '16 17:09 laurence79

As overloads to Select?

Yes.

I'm happy to amend the PR if that helps?

Would be very helpful, thanks!

vkhorikov avatar Sep 13 '16 17:09 vkhorikov

So I've run into a blocker here.

The methods

public static Maybe<K> Select<T, K>(this Maybe<T> maybe, Func<T, K> selector)
    where T : class
    where K : class

and

public static K? Select<T, K>(this Maybe<T> maybe, Func<T, K> selector)
    where T : class
    where K : struct

have the same signature. Despite the different type constraints. More info here https://blogs.msdn.microsoft.com/ericlippert/2009/12/10/constraints-are-not-part-of-the-signature/

The solution to this isn't immediately apparent to me 😕

(My original code had Func<T, K?> selector, but of course this isn't right - the func itself should not return a nullable)

laurence79 avatar Sep 14 '16 10:09 laurence79

Ah, indeed, return values also don't count as overloads. Maybe we can rename Select for structs to some other method? How about SelectStruct?

vkhorikov avatar Sep 16 '16 12:09 vkhorikov

@laurence79 Is this PR still active? Please, fix the merge conflicts or say something :)

SuperJMN avatar Nov 07 '21 21:11 SuperJMN