题
这是在C#讨好的优点
什么是上的咖喱功能实现部分功能的应用程序的优点
解决方案
在C#讨好的优点是,它允许C#开发者在一个函数编程风格发展。
想一想LINQ。 LINQ查询允许在一个方法作为参数传递:
someCollection.Where(x => x.someVal == 1);
x.someVal == 1
被评价为一个函数,然后使用Where
在它自己的执行的返回值。
这是一个例子,大多数.NET 3开发人员都熟悉,但很少有人意识到,他们在功能编程正在涉足。但无库里的能力,LINQ将是不可能的。
...厚福,对于我的智能屁股评论弥补了。
其他提示
从维基百科
柯里实际上不是非常 从我们做什么不同的时候,我们 计算功能,对于一些给定 在一张纸的值。
采取功能
f(x,y) = y / x
要评估
f(2,3)
中,首先,与x
替换2
。由于结果是在y中一个新的函数,这个函数g(Y)可以被定义为
g(y) = f(2,y) = y / 2
接下来,
y
替换3
参数提供的结果,
g(3) = f(2,3) = 3 / 2
。在纸,采用经典的符号, 它只是我们似乎做这一切在 同一时间。但是,实际上的情况下, 在一张替换参数 纸,它是顺序执行 (i.e.partially)。每次更换 内的结果的功能 功能。正如我们依次更换 每一个参数,我们是在讨好 功能为越来越简单 原来的版本。最终, 我们最终的功能链 在演算,其中每个 函数只有一个参数,以及 多参数的函数通常是 在咖喱形式表示。
有讨好的实际动机 是很经常的功能 通过提供一些但不是所有获得 自变量的函数咖喱 (通常称为局部应用)是 有用;例如,许多语言 具有类似的功能或操作 加一。柯里可以很容易地 定义这些功能。
如果你的问题是如何实现在C#讨好,这里有一个例子
public Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> func)
{
return p1 => p2 => func(p1, p2);
}
柯里可以在支持闭包(lambda表达式),并且是用于像在UI编程部分的功能应用,其中所有必需的功能未启用的执行输入接收到的有用的任何语言来实现,所以咖喱函数围绕与已经通过接收到的输入在它捕获。
我发现部分功能应用,而不是钻营,当我想重用代码是有用的。
要明确,因为讨好和局部功能的应用程序的定义似乎得到模糊,通过部分功能应用我的意思是利用函数与N个参数,并将其转换成与N-1参数的函数。
在特别是,它编写单元测试时一直得心应手。因为我会写几百个单元测试中,我尝试重用测试代码尽可能。所以我可以有一个共同的测试方法,它接受委托的方法我想测试,加上一些参数,该方法和预期结果。公共测试方法将执行该方法与测试下提供的参数,并且将有几个断言的结果进行比较,以预期的结果。
问题是当我想测试具有比代表多个参数被传递到公共测试方法的方法。可以写另一种常见的测试方法,其是相同的第一个,除了采取了与代表一个不同的签名。这似乎是在重复自己,但是。为了避免编写这样重复的代码,我可以使用部分功能应用到转换委托服用,就是说,两个参数,成代表服用的单个参数。现在我可以使用共同的测试方法测试其采取任一个或两个参数的方法。
下面是我用固定的中传递委托的参数之一的辅助方法之一:
/// <summary>
/// Fixes an argument of an action delegate, creating a closure that combines the
/// delegate and the argument value.
/// </summary>
/// <returns>An action delegate which takes only one argument.</returns>
public static Action<TIn1> FixActionArgument<TIn1, TIn2>(Action<TIn1, TIn2> action,
TIn2 argumentValue)
{
return in1 => action(in1, argumentValue);
}
一个简单柯里将是
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
Func<double, double, double, double, double> newTonLaw = (m1, m2, r, g) => ((m1 * m2) / Math.Pow(r,2)) * g;
// Mass of Earth= 5.98 * 10e24 , Gravitational Constant = 6.6726 * 10e-11
Func<double, double, double> onEarth = (m2, r) => newTonLaw.Invoke(5.98 * 10e24, m2, r, 6.6726*10e-11);
// Mass of Moon= 7.348x10e22 , Gravitational Constant = 6.6726 * 10e-11
Func<double, double, double> onMoon = (m2, r) => newTonLaw.Invoke(7.348 * 10e22, m2, r, 6.6726 * 10e-11);
Trace.WriteLine(onEarth(70, 6.38 * 10e6)); // result 686.203545562642
Trace.WriteLine(onMoon(70, 6.38 * 10e6)); // result 8.43181212841855
}
}
}