代码之家  ›  专栏  ›  技术社区  ›  masoud ramezani

咖喱的好处是什么?(实现部分功能)

  •  15
  • masoud ramezani  · 技术社区  · 16 年前

    咖喱的好处是什么?

    在当前函数上实现部分函数应用的好处是什么?

    5 回复  |  直到 16 年前
        1
  •  1
  •   Justin Niessner    16 年前

    使用C语言的优势在于,它允许C语言开发人员以函数式编程风格进行开发。

    想想林肯。LINQ查询允许您将方法作为参数传入:

    someCollection.Where(x => x.someVal == 1);
    

    x.someVal == 1 作为函数求值,然后 Where 在自己的执行中使用返回值。

    这是一个大多数.NET3开发人员都熟悉的例子,但很少有人意识到他们正在涉足函数编程。没有咖喱的能力,林肯是不可能的。

    …希望能弥补我的愚蠢评论。

        2
  •  12
  •   David Pfeffer    16 年前

    Wikipedia

    咖喱其实不是很好吃 不同于我们 计算某个给定值的函数 一张纸上的值。

    承担职能 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

    在纸上,用经典符号, 只是我们似乎都在 同时。但是,事实上,当 替换 纸,按顺序完成 (即部分)。每次更换 结果在 功能。按顺序替换 每次争论,我们都在讨好 功能变得越来越简单 原版的版本。最终, 我们最终得到一系列的功能 在lambda微积分中,每个 函数只接受一个参数,并且 多参数函数通常是 以咖喱形式表示。

    讨好的实际动机 是不是经常 通过提供部分而不是全部获得 一个curried函数的参数 (通常称为部分应用程序)是 有用;例如,许多语言 具有类似于 普鲁斯酮咖喱使它很容易 定义这些函数。

        3
  •  12
  •   Nagaraj    16 年前

    如果您的问题是如何在c中实现curring,那么下面是一个示例

    public Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> func)
        {
            return p1 => p2 => func(p1, p2);
        }
    

    curring可以用任何支持闭包(lambdas)的语言实现,对于部分函数应用程序(如在ui编程中)非常有用,在ui编程中,执行函数所需的所有输入都没有收到,因此curryed函数被传递出去,而已接收的输入被捕获。在里面。

        4
  •  1
  •   Simon Elms    13 年前

    我发现当我想重用代码时,部分函数应用程序(而不是curring)非常有用。

    为了清楚起见,由于curring和部分函数应用的定义似乎变得模糊,所以通过部分函数应用,我的意思是取一个具有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);
    }
    
        5
  •  -1
  •   zawhtut    11 年前

    简单的咖喱

    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
            }
        }
    }