C#的lambda - 库里用例库里、lambda

2023-09-03 08:46:33 作者:笑你像狗.

我读This文章,我发现很有意思。

I read This article and i found it interesting.

要概括起来为那些谁不想读了整个帖子。作者实现了一个名为库里这样的高阶函数(没有他的内部类由我重构):

To sum it up for those who don't want to read the entire post. The author implements a higher order function named Curry like this (refactored by me without his internal class):

 public static Func<T1, Func<T2, TResult>> 
             Curry<T1, T2, TResult>(this Func<T1, T2, TResult> fn)
 {
     Func<Func<T1, T2, TResult>, Func<T1, Func<T2, TResult>>> curry = 
     f => x => y => f(x, y);
     return curry(fn);
 }

这给了我们采取前pression如F的能力(X,Y) 例如。

That gives us the ability to take an expression like F(x, y) eg.

Func<int, int, int> add = (x, y) => x + y;

和调用它的F.Curry()(X)(Y)的方式;

and call it in the F.Curry()(x)(y) manner;

这部分我的理解,我觉得它在一个怪异的方式冷静。我无法左右换我的头实际用例的这种做法。何时何地这种技术是必要的,什么都可以从中得到了什么?

This part i understood and i find it cool in a geeky way. What i fail to wrap my head around is the practical usecases for this approach. When and where this technique is necessary and what can be gained from it?

在此先感谢。

编辑:  在最初的3响应据我所知,收益将是在某些情况下,当我们创建一个从咖喱一些参数没有被重新evalued一个新的功能。 我建立在C#这个小测试(记住,我只关心在C#实现,而不是咖喱理论一般):

Edited: After the initial 3 responses i understand that the gain would be that in some cases when we create a new function from the curried some parameters are not re evalued. I made this little test in C# (keep in mind that i'm only interested in the C# implementation and not the curry theory in general):

public static void Main(string[] args)
{
    Func<Int, Int, string> concat = (a, b) => a.ToString() + b.ToString();
    Func<Int, Func<Int, string>> concatCurry = concat.Curry();
    Func<Int, string> curryConcatWith100 = (a) => concatCurry(100)(a);

    Console.WriteLine(curryConcatWith100(509));
    Console.WriteLine(curryConcatWith100(609));
}

    public struct Int
    {
        public int Value {get; set;}

        public override string ToString()
        {
             return Value.ToString();
        }

        public static implicit operator Int(int value)
        {
            return new Int { Value = value };
        }
    }

在2个连续调用curryConcatWith100的toString()方法评价调用两次(一次为每个调用)的值100,所以我没有看到在评价任何好处在这里。我失去了一些东西?

On the 2 consecutive calls to curryConcatWith100 the ToString() evaluation for the value 100 is called twice (once for each call) so i dont see any gain in evaluation here. Am i missing something ?

推荐答案

它更容易首先考虑FN(X,Y,Z)。这可以通过使用FN(X,Y)给你一个函数,只需要一个参数,在Z咖喱。需要的无论什么要与x和单独ÿ完成可以通过返回的函数持有到一个封闭件来完成,并存储

Its easier to first consider fn(x,y,z). This could by curried using fn(x,y) giving you a function that only takes one parameter, the z. Whatever needs to be done with x and y alone can be done and stored by a closure that the returned function holds on to.

现在你调用返回的函数几次不同值用于z,而无需重新计算部分所需的X和Y

Now you call the returned function several times with various values for z without having to recompute the part the required x and y.

编辑:

有有效的两个原因咖喱。

There are effectively two reasons to curry.

至于卡梅伦说来转换一个函数,它说2参数成函数,只需要1调用带有一个参数,这个咖喱功能的结果是一样的调用原来​​的2个参数。

As Cameron says to convert a function that takes say 2 parameters into a function that only takes 1. The result of calling this curried function with a parameter is the same as calling the original with the 2 parameters.

使用Lambda表达式present在C#这有限的价值,因为它们可以提供反正这种效果。虽然你是使用C#2,然后在你的问题的库里功能有更大的价值。

With Lambdas present in C# this has limited value since these can provide this effect anyway. Although it you are use C# 2 then the Curry function in your question has much greater value.

另一个原因咖喱是因为我先前所说。为了让复杂/昂贵的操作上演,并在最后一个参数(S)提供给咖喱功能重复使用多次。

The other reason to curry is as I stated earlier. To allow complex/expensive operations to be staged and re-used several times when the final parameter(s) are supplied to the curried function.

这类型的钻营是不是忠实地可能在C#中,它确实需要一个功能性的语言,可以在本机咖喱其任何功能获得了这幅。

This type of currying isn't truely possible in C#, it really takes a functional language that can natively curry any of its functions to acheive.

通过你提到的咖喱参数减少是在C#2有用的,但由于lambda表达式大大解除值在C#3。

Parameter reduction via the Curry you mention is useful in C# 2 but is considerably de-valued in C# 3 due to Lambdas.

 
精彩推荐
图片推荐