Need help understanding lambda (currying)
i am reading Accelerated C# i don't really understand the fo开发者_如何学JAVAllowing code:
public static Func<TArg1, TResult> Bind2nd<TArg1, TArg2, TResult> (
this Func<TArg1, TArg2, TResult> func,
TArg2 constant )
{
return (x) => func( x, constant );
}
in the last line what is x referring to? and there's another:
public static Func<TArg2, Func<TArg1, TResult>> Bind2nd<TArg1, TArg2, TResult>
( this Func<TArg1, TArg2, TResult> func )
{
return (y) => (x) => func( x, y );
}
How do i evaluate this? (y) => (x) => func( x, y )
what is passed where ... it does confusing.
Let's first simplify the code:
Func<int, int> B(Func<int, int, int> f, int c)
{
return x=>f(x, c);
}
This is just the same as:
class Locals
{
public int c;
public Func<int, int, int> f;
public int Magic(int x) { return f(x, c); }
}
Func<int, int> B(Func<int, int, int> f, int c)
{
Locals locals = new Locals();
locals.f = f;
locals.c = c;
return locals.Magic;
}
Now is it clear what x refers to? x is the parameter to function "Magic".
Now you can use B like this:
Func<int, int, int> adder = (a, b)=>a+b;
Func<int, int> addTen = B(adder, 10);
int thirty = addTen(20);
Make sense? See what is happening here? We're taking a function of two parameters and "fixing" one of the parameters to a constant. So it becomes a function of one parameter.
The second example takes that one step further. Again, simplify to get rid of the cruft so that you can understand it more easily:
Func<int, Func<int, int>> B2(Func<int, int, int> f)
{
return y=>x=>f(x,y);
}
This is the same as
class Locals3
{
public int y;
public int Magic3(int x)
{
return x + this.y;
}
}
class Locals2
{
public Func<int, int, int> f;
public Func<int, int> Magic2(int y)
{
Locals3 locals = new Locals3;
locals.y = y;
return locals.Magic3;
}
}
Func<int, Func<int, int>> B2(Func<int, int, int> f)
{
Locals2 locals = new Locals2();
locals.f = f;
return locals.Magic2;
}
So you say
Func<int, int, int> adder = (a, b)=>a+b;
Func<int, Func<int, int>> makeFixedAdder = B2(adder);
Func<int, int> add10 = makeFixedAdder(10);
int thirty = add10(20);
B is a parameter fixer. B2 makes a parameter fixer for you.
However, that's not the point of B2. The point of B2 is that:
adder(20, 10);
gives the same result as
B2(adder)(20)(10)
B2 turns one function of two parameters into two functions of one parameter each.
Make sense?
x is the parameter of the lambda, it is of type TArg1.
It can be helpful to pronounce the => as "maps to" as in "x maps to a new function with a constant of type TArg2 substituted into the original function delegate, func."
The variable x is an unbound variable. That represents an argument to the returned function from calling Bind2nd
.
A few hours with Scheme would help you here, but try this.
When you call Bind2nd
the returned result is a function. That function is defined as
(x) => func (x, constant)
Now that you have the above assigned to a variable, lets say lambda
, you can call that function via the lambda
variable
lambda(x);
The x
defined in Bind2nd
is just a variable that represents an argument to the function that will be returned to you.
A lambda expression is shorthand for anonymous method. Like anonymous method, lambda expression is assigned to delegate types. All conditions that apply for anonymous methods also apply to lambda expressions.
=> is called lambda operator, which is read as “goes to”. The left side of the operator specifies the input parameters separated by comma, and the right side specifies an expression or statement block which is called lambda body. (p1, p2, p3, …pN) => expression If you have only one parameter then you can skip the parenthesis p1 => expression;
I have written a small blog explaining lambda expression here Lambda Expression
精彩评论