XDracam / unity-corelibrary

Collection of classes and extension methods that make life with Unity3D more comfortable
MIT License
16 stars 3 forks source link

IfAllNotNull - the mapN of nullables #51

Open XDracam opened 5 years ago

XDracam commented 5 years ago

In functional languages, if you have a number of possibly nonexisting values and want to call a function on these values only when all of them are present, you can use a simple utility:

-- this is unsugared haskell, don't be confused 
-- map2 is not a standard function, because these people know more math

start :: Maybe Vector3
end :: Maybe Vector3

lerp :: Float -> Maybe Vector3 -> Maybe Vector3 -> Maybe Vector3
lerp p start end = map2 start end ((\start end) -> start + (end - start) * p))

In the above case, lerp returns a result when both start and end are defined, and effectively "null" when one of them are not.

I propose a series of overloaded methods called Utils.IfAllNotNull, which may look like this:

public TRes IfAllNotNull<A, B, C, TRes>(A a, B b, C c, Func<A, B, C, TRes> fn) 
where A : class where B : class where C : class
{
    if (Utils.IsNull(a) || Utils.IsNull(a) || Utils.IsNull(c)) return null;
    return fn(a, b, c);
}

These also need versions for Actions in case nothing needs to be returned. C# is a side-effectful language after all.

I'd allow between two and five arguments, I think. But these are arbitrary numbers. The one-arg case exists (.IfNotNull) and anything more than five would probably look pretty unmaintainable.

Probably going to use code generation for this too.