The opposite of BenVlodgi's answer: i.e. AnonRecursiveFiboFunc<TArg> has only one template parameter, therefore all the template arguments passed to Recursive<TArg, TArg, TArg, TArg> recursive are the same, therefore there only needs to be one of them.
You can rewrite the code as:
delegate Func<T, T, T, T> Recursive<T>(Recursive<T> r);
private static Func<TArg, TArg, TArg, TArg>
AnonRecursiveFiboFunc<TArg>(Func<Func<TArg, TArg, TArg, TArg>,
Func<TArg, TArg, TArg, TArg>> function)
{
Recursive<TArg> recursive =
rec => (step, fibo1, fibo2) =>
function(rec(rec))(step, fibo1, fibo2);
return recursive(recursive);
}
Given that all the arguments passed to Func are the same, you can reduce it further by defining your own delegate (which I named Function3) as follows:
delegate T Function3<T>(T arg1, T arg2, T arg3);
delegate Function3<T> Recursive<T>(Recursive<T> r);
private static Function3<TArg>
AnonRecursiveFiboFunc<TArg>(Func<Function3<TArg>,
Function3<TArg>> function)
{
Recursive<TArg> recursive =
rec => (step, fibo1, fibo2) =>
function(rec(rec))(step, fibo1, fibo2);
return recursive(recursive);
}