解释此代码

时间:2010-03-08 14:38:08

标签: c# lambda

请解释此代码:

public static Func<TInput1, TOutput> Curry<TInput1, TOutput>(this Func<TInput1, TOutput> f)
{
    return x => f(x);
}

OR

Func<Int32, Int32> SubtractOne = x => x - 1;

这些技术的名称是什么?

4 个答案:

答案 0 :(得分:8)

第一个样本实际上是无操作,因为输入函数已经是curry形式;它只是为调用添加了额外的间接级别。如果您对currying感兴趣,请查看the information on Wikipedia作为起点。

第二个示例创建一个名为SubtractOne的{​​{3}},它将从传递的参数中减去一个。{/ p>

答案 1 :(得分:3)

这是一种名为lambda expression的新语言功能。

第二个创建一个函数,它接受一个名为Int32的{​​{1}}并返回一个等于x的{​​{1}},然后将该函数分配给一个委托类型的变量名为Int32

它等同于以下C#1.0代码:

x - 1

答案 2 :(得分:3)

第一个片段只有在伴有几个类似的重载时才有意义。它可能只是完成一组名为Curry的方法。这个词来自名称Haskell Curry,指的是编程语言(或库)中为函数提供所需参数子集的能力,以便获得接受其余函数的另一个函数。通过一个例子更容易理解:

void Foo(int a, string b, bool c) { ... }

您可以调用它来提供所有三个参数:

Foo(123, "hi", false);

但是在讨好时,你可以这样做:

var foo123 = Foo(123);

它会返回另一个带剩余两个参数的函数,所以我们说它将第一个参数“绑定”到值123.但是如果你可以使用原始函数进行咖喱,你可以使用新函数:

var foo123Hi = foo123("hi");

最后提供最后一个论点:

foo123Hi(false);

最后我们有三个参数,现在我们对Foo的定义实际上是真实的。

在许多函数式语言中(在Haskell和Curry语言中不出所料),这种语言已经内置。在C#中它不是,尽管你可以通过提供一组重载来部分模拟它,例如:

Action<string, bool> Foo(int a)
{
    return (b, c) => Foo(a, b, c);
}

Action<bool> Foo(int a, string b)
{
    return c => Foo(a, b, c);
}

但这仍然不太正确,因为在第一个示例中,返回的Action<string, bool>不会直接咖喱。

因此,有时会尝试提供一个currying库,以便在任何函数上进行curry。

但是使用足够简单的lambda语法,实际上并不清楚任何库解决方案都会有用。毕竟,lambda是绑定一个参数的一种非常简单的方法,如上面的例子所示。所以我不确定“Curry”方法库的使用范围有多广泛。 =>运算符更清晰,更少笨重,更强大,更易读,并且已经内置。

答案 3 :(得分:1)

var result = SubtractOne(5);
Assert.AreEqual(4, result);