2010-03-08 84 views
4

请解释这个代码:解释这个代码

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

第二个是函数式编程的东西..现在不记得名字了。 – Earlz 2010-03-08 14:41:11

+5

问题到底是什么? – 2010-03-08 14:42:34

+0

这种技术的名称是什么? – 2010-03-08 14:45:17

回答

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>不会直接咖喱-能够。

所以有时候会尝试提供一个咖啡库来启用对任何功能的控制。

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

+0

+1谢谢你的好例子。 – 2010-03-08 16:06:42

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

这是一种新的语言功能,称为lambda expression

第二个使一个函数,它接受一个Int32命名x并返回一个Int32等于x - 1,则该函数分配给名为Func<Int32, Int32>委托类型的变量。

这等同于以下的C#1.0代码:

delegate int MyFunc(int x); 
static int SubtractOneFunction(int x) { return x - 1; } 

MyFunc SubtractOne = new MyFunc(SubtractOneFunction); 
+1

那么,在这种情况下,它是等价的......但不是在一般情况下,因为lambda表达式(和C#2.0匿名代理)可以捕获本地变量,这在C#1.0中是不可能的 – 2010-03-08 14:58:35

8

第一样品是有效无操作作为输入功能已经在咖喱形式;它只是给呼叫增加了一个额外的间接级别。如果您对咖喱感兴趣,请以the information on Wikipedia作为起点。

第二个示例创建一个名为SubtractOnelambda expression,它将从传递的参数中减去一个。