请解释此代码:
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;
这些技术的名称是什么?
答案 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);