How does this C# function composition method work? - c#

I've occured the following code:
public static class FuncUtils
{
public static Func<T1, T3> Compose<T1, T2, T3> (Func<T1, T2> f1, Func<T2, T3> f2)
{
return a => f2(f1(a));
}
}
What's the biggest mystery for me is this one
return a => f2(f1(a));
Can you explain how does it work?

It will return a Func<T1, T3>, that is a function (delegate) that takes some parameter of type T1 and returns a result of type T3 . Let's call the returned Func f
The result (returned value) of f is just the result from the 2 function parameters f1 and f2 composed (as in math function composition) on any parameter given.
More on f, the returned Func:
Apply f1 on the parameter a (of type T1), get some result b (of type T2), then apply f2 on b , call this result c (of type T3). c will be the result for any a passed to f .

You need to understand the concept of higher order functions to make sense of the above method. Higher order functions are modeled as delegates in .NET and therefore in c#. A delegate is a data type that represents a method to be called. So you when you execute your method, the result you get is another method that you need to call to get your result (hence higher order function).
So let's dissect your method:
The parameters Func<T1, T2> f1 and Func<T2, T3> f2 are delegates, which each represent a method. You can call these methods by calling the delegates:
//You need a value of type T1, here represented by the variable a
T2 value = f1(a);
The call must look like this, because this is how the delegate id defined:
public delegate TResult Func<T, TResult>(T item);
You can call f2 like you call f1, just with a different parameter type. Since T2 is the return of f1 and the parameter of T2, you can just pass the result of f1 to f2:
T2 result = f2(value);
Or inline:
T2 result = f2(f1(a));
You will find this in your method, which means it performs a nested call of the two methods.
In a special twist, Compose does not call the methods and return the result, it returns a higher order function by itself. It uses the lambda operator => for this, which is another way to create a delegate. To the left of the lambda operator is a, which is an arbitrary name for the new function's parameter. The type of a is T1, which the compiler can figure out by type inferrence.
So in the end the caller has to execute the returned delegate to get the final result. This is called defered execution and is commonplace in LINQ.
You can think of thw Compose method of a way to nest the call to two methods before you actually make the call.

Related

Generic Type inference has a strange behavior

I hope someone can explain me a strange behavior from the C# type inference system, when attempting to "partially apply" functions.
Assume I have following code:
int Add(int a, int b) => a + b;
Why can the inference system not infer the type of X if I declare it like following:
var add1 = (x) => Add(1, x); // does not work: CS8917: The delegate type could not be inferred.
var add1 = (int x) => Add(1, x); // does work
var add_1 = PartiallyApply(Add, 1);
Func<T1, T2, TResult> PartiallyApply<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 param) {
return (p2) => func(param, p2);
}
The second version makes sense, if the inference system runs from top to bottom, so you have to declare everything before you use it.
The type inference system of F# goes the other way around, and checks the usage of the function to infer the used types.
I would really appreciate some ideas and if I can overcome this issue somehow using !inline! declarations.
I know there are other ways to overcome this issue, by using explicit typing but that's not the route I want to take.
Thanks in adavance everyone
You must explicitly give the type of X , for this function to work properly !

C#: List of functions with variable number of arguments

Is it possible in C# to have higher-order function which takes a function with an arbitrary number and type of arguments and return values, e.g.,
// No valid C# code
void MyFunction(Func f)
{
// do something
}
MyFunction(string.Join); // type: Func<String, IEnumerable<String>, String>
MyFunction(string.CompareTo); // type: Func<object, int>
// ...
I guess, this question really boils down to whether there's a most generic type for functions which can hold any function with possibly different number and type of arguments.
My use-case is the following: I have a method which takes a MethodInfo object. Currently, I do something like
DoSomething(((Func<object, int>)string.CompareTo).Method)
However, I'd have to repeat this for every different kind of function I expect. I'd prefer a solution in which DoSomething could by itself determine the type, so I just give it the Function itself instead of the MethodInfo object.
EDIT:
To be more precise, I'm writing a Linq-To-X provider using ReLinq. I got some example code from a tutorial blog on this topic (https://www.codeproject.com/Articles/42059/re-linq-ishing-the-Pain-Using-re-linq-to-Implement and https://weblogs.asp.net/dixin/understanding-linq-to-sql-10-implementing-linq-to-sql-provider). For eager execution functions like Sum or Count, I need to wrap them into a MethodCallExpression object.
In the example code, it is solved like this:
public static IQuery CountToSql<T>(this IQueryable<T> source)
{
ArgumentChecker.CheckNull(source, nameof(source));
var expression =
Expression.Call(
null,
GetMethodInfo(Queryable.Count, source),
new Expression[] { source.Expression }
);
return ToQuery(expression, ((DbQueryable<T>)source).SyntaxProvider);
}
private static MethodInfo GetMethodInfo<T1, T2>(Func<T1, T2> f, T1 unused1 => f.Method;
private static MethodInfo GetMethodInfo<T1, T2, T3>(Func<T1, T2, T3> f, T1 unused1, T2 unused2) => f.Method;
// ...
However, I don't want to write this for every type of function (e.g., Queryable.Sum, Queryable.Count, ...). The current solution necessitates it. I just want one single method that can handle all, as they look the same for 90%.
It seem strange that you need to call such different delegates from one place.
I think you need something like "EventDispatcher", when your code got data that should be then casted to object, but after that inside a call you want to operate a real objects.
If I wrong please tell more about task.
If I right, you have to replace reflections by generics. Create method that will wrap you delegate by Action.
public Action<object> WrapCall<T, K>( Func<T, K> func)
{
return (data) => func((T)data);
}
public Action<object, object> WrapCall<T1, T2, K>(Func<T1, T2,K> func)
{
return (t1Data, t2Data) => func((T1)t1Data, (T2)t2Data);
}
and so one.
It may be not solve your problem but will helps you to find solution in other way.

How to put a lambda expression in a variable and then pass it to a s/r

Sorry for this question: I am somehow new to lambda expressions.
I have a library and some functions and I want to pass the to execute some actions. Therefore I thought about putting some code in a lamba expression, associate it to a variable and the make it execute from the library s/r.
In short (pseudocode):
var1 = { ...code1...};
var2 = { ...code2...};
ExternalFunction(??? var1, ??? var2);
ExternalFunc(??? var1, ???var2)
{
Console.WriteLine("Executing code 1");
???
Console.WriteLine("Executing code 2");
???
}
Depending on what your code should do you will need a parameter of type Action<T1, T2, ...> or Func<T1, T2, ...>. However you cannot create your method so that it runs any arbitrary code, you have to provide a return-type and the parameters of course.
So if your code of block returns an int and expects a string you may write this:
Func<string, int> myFunc = x => Convert.ToInt32(x) + 1;
void ExternalFunc(Func<T1, T2> myFunc, T1 param) {
var myInt = myFunc(param);
}
Now call it like this:
ExternalFunc(myFunc, "1");
However you cannot expect this code to run also:
Func<int> myOtherFunc = () => 1;
ExternalFunc(myOtherFunc)
because myOtherFunc must be of type Func<T1, T2>, not just Func<T> to be passed to ExternalFunc.
Moreover if your code-block should not return anything (void), use an Action<...> instead of Func<...>.
Well, here's your standard documentation for lambdas:
https://msdn.microsoft.com/en-us/library/bb397687.aspx?f=255&MSPPError=-2147217396
if you're looking for the type inference of a lambda, it's a Func. So the parameter text you're looking for is probably this:
public void youtExternalFunction(Func<> var1, Func<T, U> var2)

Create delegate at runtime [duplicate]

How can I create a Delegate with types only known at run time ?
I would like to do the following :
Type type1 = someObject.getType();
Type type2 = someOtherObject.getType();
var getter = (Func<type1, type2>)Delegate.CreateDelegate(
typeof(Func<,>).MakeGenericType(type1, type2), someMethodInfo);
How can I achieve something similar ?
I suspect you want Expression.GetFuncType as a simpler way of doing your typeof(...).MakeGenericType operation.
var delegateType = Expression.GetFuncType(type1, type2);
Delegate getter = Delegate.CreateDelegate(delegateType, someMethodInfo);
You can't have a compile-time type for getter that's more specific than Delegate though1, because you simply don't know that type at compile-time. You could potentially use dynamic though, which would make it easier to invoke the delegate:
dynamic getter = ...;
var result = getter(input);
1 As noted in comments, you could cast to MulticastDelegate, but it wouldn't actually buy you anything.
You could create a generic method for that:
public Func<T1, T2> GetFunc<T1, T2>(T1 Object1, T2 Object2, MethodInfo Method)
{
return (Func<T1, T2>)Delegate.CreateDelegate(typeof(Func<,>).MakeGenericType(typeof(T1), typeof(T2)), Method);
}
And I bet you can do something using the same philosophy with the Method to avoid all this reflection stuff.
Obs: that would work only if T1 and T2 are typed variables. If they are as object you'll get a Func<object, object>. But....if the objects you will give to the method are as object as well, that would be no problem at all.
And maybe you can even use Func<object, object> always, depending on your scenario.

Create delegate with types known at runtime

How can I create a Delegate with types only known at run time ?
I would like to do the following :
Type type1 = someObject.getType();
Type type2 = someOtherObject.getType();
var getter = (Func<type1, type2>)Delegate.CreateDelegate(
typeof(Func<,>).MakeGenericType(type1, type2), someMethodInfo);
How can I achieve something similar ?
I suspect you want Expression.GetFuncType as a simpler way of doing your typeof(...).MakeGenericType operation.
var delegateType = Expression.GetFuncType(type1, type2);
Delegate getter = Delegate.CreateDelegate(delegateType, someMethodInfo);
You can't have a compile-time type for getter that's more specific than Delegate though1, because you simply don't know that type at compile-time. You could potentially use dynamic though, which would make it easier to invoke the delegate:
dynamic getter = ...;
var result = getter(input);
1 As noted in comments, you could cast to MulticastDelegate, but it wouldn't actually buy you anything.
You could create a generic method for that:
public Func<T1, T2> GetFunc<T1, T2>(T1 Object1, T2 Object2, MethodInfo Method)
{
return (Func<T1, T2>)Delegate.CreateDelegate(typeof(Func<,>).MakeGenericType(typeof(T1), typeof(T2)), Method);
}
And I bet you can do something using the same philosophy with the Method to avoid all this reflection stuff.
Obs: that would work only if T1 and T2 are typed variables. If they are as object you'll get a Func<object, object>. But....if the objects you will give to the method are as object as well, that would be no problem at all.
And maybe you can even use Func<object, object> always, depending on your scenario.

Categories