Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function composition

Below a Compose function. If f and g are unary functions which return values, then Compose(f,g) returns a function which when called on x performs the equivalent to f(g(x)).

static Func<X, Z> Compose<Z, Y, X>(Func<Y, Z> f,Func<X, Y> g) 
{ return x => f(g(x)); }

Here's a couple of simple Func values which can be composed:

Func<int, bool> is_zero = x => { return x == 0; };

Func<int, int> mod_by_2 = x => { return x % 2; };

E.g. this works:

Console.WriteLine(Compose(is_zero, mod_by_2)(4));

However, if I instead have these equivalent static methods:

static bool IsZero(int n) { return n == 0; }

static int ModBy2(int n) { return n % 2; }

the same example doesn't work with those. I.e. this produces a compile time error:

Console.WriteLine(Compose(IsZero, ModBy2)(4));

Explicitly passing types to Compose fixes the issue:

Console.WriteLine(Compose<bool, int, int>(IsZero, ModBy2)(4));

Is there anyway to write Compose such that it works on the static methods without the explicit types?

Is this a good approach to take to implementing Compose? Can anyone make improvements to this?

like image 419
dharmatech Avatar asked Jan 03 '12 23:01

dharmatech


People also ask

What is meant by function composition?

In mathematics, function composition is an operation ∘ that takes two functions f and g, and produces a function h = g ∘ f such that h(x) = g(f(x)). In this operation, the function g is applied to the result of applying the function f to x.

What is composition function with example?

A composite function is generally a function that is written inside another function. Composition of a function is done by substituting one function into another function. For example, f [g (x)] is the composite function of f (x) and g (x). The composite function f [g (x)] is read as “f of g of x”.


1 Answers

The problem here is not the use of static methods but the use of method groups. When you use a function name as an expression without invoking it then it's a method group and must go through method group conversion. You would have the exact same problem with instance methods.

The problem you're running into is that C# can't do return type inference on method groups. Using Compose(IsZero, ModBy2)) requires the return type to be inferred for both IsZero and ModBy2 and hence this operation fails.

This is a known limitation in the inference capabilities of the C# compiler. Eric Lippert wrote an extensive blog article on this particular subject which covers this problem in detail

  • http://blogs.msdn.com/b/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx
like image 181
JaredPar Avatar answered Oct 20 '22 17:10

JaredPar