Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I can't use lambda expression inside Tuple.Create?

I know that the compiler can cast from lambda expression to Predicate.

For example:

Predicate<int> p = x => true;

is good.

But when I want to create a tuple that holds a Predicate. I tried to do this (simplified version):

Tuple<Predicate<int>> t;
t = Tuple.Create(x => true);

and I got the compilation error:

The type arguments for method 'System.Tuple.Create(T1)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

My question is what this is an error, where is the ambiguity here?

(I know I can fix it by casting:t = Tuple.Create((Predicate<int>)(x => true)); but I want to understand why the first way is not good, and also I want not to do the casting to save typing :)

like image 718
Erez Avatar asked Oct 15 '15 10:10

Erez


People also ask

Which sentence about lambda statements is not true?

Which is NOT true about lambda statements? A statement lambda cannot return a value.

What is lambda expression in Linq?

A lambda expression is a convenient way of defining an anonymous (unnamed) function that can be passed around as a variable or as a parameter to a method call. Many LINQ methods take a function (called a delegate) as a parameter.

How can we write a parameter less lambda expression?

To create a lambda expression, we specify input parameters (if there are any) on the left side of the lambda operator ->, and place the expression or block of statements on the right side of lambda operator.


1 Answers

where is the ambiguity here?

The ambiguity here is that the compiler doesn't attempt to infer the lambda expression passed to Tuple.Create based on the left hand side which already declares the desired type. What happens is type inference algorithm kicks in (regardless of you declaring the type of the variable), and fails to find a suitable match to your lambda expression as it doesn't have enough information.

This can be easily fixed with declaring the type of the tuple and explicitly telling the compiler how to infer the lambda expression:

t = Tuple.Create<Predicate<int>>(x => true);

If you want to get into the type inference algorithm and see why it fails:

Given:

Tr M<X1…Xn>(T1 x1 … Tm xm)

With a method call of the form M(E1 …Em) the task of type inference is to find unique type arguments S1…Sn for each of the type parameters X1…Xn so that the call M(E1…Em) becomes valid.

Now we start:

7.5.2.1 The first phase:

For each of the method arguments Ei:

If Ei is an anonymous function, an explicit parameter type inference (§7.5.2.7) is made from Ei to Ti

So we look what explicit parameter type inference does:

7.5.2.7 Explicit parameter type inferences

An explicit parameter type inference is made from an expression E to a type T in the following way:

· If E is an explicitly typed anonymous function with parameter types U1…Uk and T is a delegate type or expression tree type with parameter types V1…Vk then for each Ui an exact inference (§7.5.2.8) is made from Ui to the corresponding Vi.

Your anonymous function isn't explicitly type, so the compiler has no way of doing an exact inference from the parameter type Ui..Uk to proper overload of Tuple.Create.

like image 58
Yuval Itzchakov Avatar answered Oct 25 '22 09:10

Yuval Itzchakov