[ACCEPTED]-Does C# support function composition?-composition
public static class Extensions
{
public static Func<T, TReturn2> Compose<T, TReturn1, TReturn2>(this Func<TReturn1, TReturn2> func1, Func<T, TReturn1> func2)
{
return x => func1(func2(x));
}
}
Usage:
Func<int, int> makeDouble = x => x * 2;
Func<int, int> makeTriple = x => x * 3;
Func<int, string> toString = x => x.ToString();
Func<int, string> makeTimesSixString = toString.Compose(makeDouble).Compose(makeTriple);
//Prints "true"
Console.WriteLine(makeTimesSixString (3) == toString(makeDouble(makeTriple(3))));
0
I did not let the compiler check this, but 1 this should be possible:
public static Func<T3,T1> my_chain<T1, T2, T3>(Func<T2,T1> f1, Func<T3,T2> f2)
{
return x => f2(f1(x));
}
There is no specific operator / "syntax 4 sugar" for that in C# (however, in 3 F# you would use the >>
operator).
There is 2 a great blog post on this subject from Matthew Podwysocki. He 1 suggests this kind of construct in C#:
public static class FuncExtensions
{
public static Func<TSource, TResult> ForwardCompose<TSource, TIntermediate, TResult>(
this Func<TSource, TIntermediate> func1, Func<TIntermediate, TResult> func2)
{
return source => func2(func1(source));
}
}
Func<Func<int, int>, IEnumerable<int>, IEnumerable<int>> map = (f, i) => i.Select(f);
Func<Func<int, bool>, IEnumerable<int>, IEnumerable<int>> filter = (f, i) => i.Where(f);
Func<int, Func<int, int, int>, IEnumerable<int>, int> fold = (s, f, i) => i.Aggregate(s, f);
// Compose together
var mapFilterFold = map.Apply(x => x * x * x)
.ForwardCompose(filter.Apply(x => x % 3 == 0))
.ForwardCompose(fold.Apply(1, (acc, x) => acc * x));
Console.WriteLine(mapFilterFold(Enumerable.Range(1, 10)));
C# doesn't have first class support but 2 it's not particularly hard to implement. You 1 just have to write a lot of overloads.
public static class Composition
{
public static Func<T2> Compose<T1, T2>(Func<T1> f1, Func<T1, T2> f2)
{
return () => f2(f1());
}
public static Func<T1, T3> Compose<T1, T2, T3>(Func<T1, T2> f1, Func<T2, T3> f2)
{
return v => f2(f1(v));
}
}
It's not nearly as pretty, but you could 6 do:
Func<IEnumerable<T>, IEnumerable<T>> desort = l => l.OrderBy(i => i).Reverse();
Or, if you want something more composit-y 5 (that acts on the array in place):
Action<int[]> desort = a => Array.Reverse(Array.Sort(a));
Assuming 4 those methods existed...but the syntax should 3 be about right.
You could then use it in 2 the following way (assuming you went with 1 the first method above):
var arr = { 2,8,7,10,1,9,5,3,4,6 };
var desortedArr = desort(arr);
More than Linq, it's delegates, and lambda 7 expressions/statements that are similar 6 to chaining.
Func<int, string> a = p => p.ToString();
Func<string, string> b = p => "|" + p + "|";
Func<int, string> c = p => b(a(p));
The definition given in the 5 link is:
Function composition is the act 4 of pipelining the result of one function, to 3 the input of another, creating an entirely 2 new function.
And c
is clearly a new function 1 that chain call a
and b
.
No, not short of defining your own generic 3 Compose<T, U...>()
functions. C# has no built-in functionality 2 to help you out with this. (It doesn't 1 do partial application, either.)
Example for function composition in C#
f(x) ° g(x)
Func<int, int> f = x => x + 2;
Func<int, int> g = x => 3 * x;
Func<int, int> b = x => f(g(x));
int result = b(2); //Result is 8
0
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.