需要帮助了解lambda(currying)

时间:2010-09-02 05:05:36

标签: c# lambda currying

我正在阅读Accelerated C#我真的不明白以下代码:

public static Func<TArg1, TResult> Bind2nd<TArg1, TArg2, TResult> (
    this Func<TArg1, TArg2, TResult> func,
    TArg2 constant ) 
{
    return (x) => func( x, constant );
}

在最后一行x指的是什么?还有另一个:

public static Func<TArg2, Func<TArg1, TResult>> Bind2nd<TArg1, TArg2, TResult>
( this Func<TArg1, TArg2, TResult> func )
{
    return (y) => (x) => func( x, y );
}

我如何评价这个? (y) => (x) => func( x, y )通过哪里......它确实令人困惑。

4 个答案:

答案 0 :(得分:19)

让我们先简化代码:

Func<int, int> B(Func<int, int, int> f, int c)
{
    return x=>f(x, c);
}

这与:

相同
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;
}

现在很清楚x指的是什么? x是“魔术”功能的参数。

现在你可以像这样使用B:

Func<int, int, int> adder = (a, b)=>a+b;
Func<int, int> addTen = B(adder, 10);
int thirty = addTen(20);

有意义吗?看看这里发生了什么?我们正在使用两个参数的函数并将其中一个参数“固定”为常量。所以它成为一个参数的函数。

第二个例子更进了一步。再次,简化以摆脱困境,以便您可以更容易地理解它:

Func<int, Func<int, int>> B2(Func<int, int, int> f) 
{
    return y=>x=>f(x,y);
}

这与

相同
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;
}

所以你说

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是参数修复工具。 B2 为您制作参数修复程序

然而,这不是B2的。 B2的重点是:

adder(20, 10);

给出与

相同的结果
B2(adder)(20)(10)

B2 将两个参数的一个函数转换为两个函数,每个参数一个

有意义吗?

答案 1 :(得分:1)

x是lambda的参数,它的类型为TArg1。

发音=&gt;会很有帮助作为“映射到”,如“x映射到一个新函数,其中TArg2类型的常量被替换为原始函数委托,func。”

答案 2 :(得分:1)

变量x是未绑定的变量。这表示调用Bind2nd返回函数的参数。

使用Scheme几个小时会帮助你,但试试这个。

当您致电Bind2nd时,返回的结果是一个函数。该功能定义为

(x) => func (x, constant)

现在您已将上述内容分配给变量,我们可以说lambda,您可以通过lambda变量调用该函数

lambda(x);

x中定义的Bind2nd只是一个变量,表示将返回给您的函数的参数。

答案 3 :(得分:1)

lambda表达式是匿名方法的简写。与匿名方法一样,lambda表达式被分配给委托类型。适用于匿名方法的所有条件也适用于lambda表达式。

=&GT;被称为lambda运算符,被读作“转到”。运算符的左侧指定以逗号分隔的输入参数,右侧指定称为lambda body的表达式或语句块。 (p1,p2,p3,... pN)=&gt;表达式如果只有一个参数,则可以跳过括号p1 =&gt;表达;

我写了一篇小博客,在这里解释lambda表达式Lambda Expression