gpt4 book ai didi

C# lambda - curry 用例

转载 作者:可可西里 更新时间:2023-11-01 08:03:23 27 4
gpt4 key购买 nike

我读了This article我发现它很有趣。

为那些不想阅读整篇文章的人总结一下。作者实现了一个叫Curry的高阶函数是这样的(我自己重构的,没有他的内部类):

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

这使我们能够采用 F(x, y) 这样的表达式例如。

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

并以F.Curry()(x)(y)的方式调用;

这部分我理解了,我发现它以一种极客的方式很酷。我没有想到的是这种方法的实际用例。何时何地需要这种技术,可以从中获得什么?

提前致谢。

编辑: 在最初的 3 个响应之后,我了解到在某些情况下,当我们从柯里化(Currying)创建一个新函数时,一些参数不会被重新评估。我在 C# 中做了这个小测试(请记住,我只对 C# 实现感兴趣,而不是一般的 curry 理论):

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

在对 curryConcatWith100 的 2 次连续调用中,对值 100 的 ToString() 求值被调用两次(每次调用一次),因此我看不到这里的求值有任何好处。我错过了什么吗?

最佳答案

Currying 用于将具有 x 参数的函数转换为具有 y 参数的函数,因此它可以传递给另一个需要具有 y 参数的函数的函数。

例如,Enumerable.Select(this IEnumerable<T> source, Func<TSource, bool> selector)采用带有 1 个参数的函数。 Math.Round(double, int)是一个有 2 个参数的函数。

您可以使用柯里化(Currying)来“存储”Round作为数据函数,然后将该柯里化(Currying)函数传递给 Select像这样

Func<double, int, double> roundFunc = (n, p) => Math.Round(n, p);
Func<double, double> roundToTwoPlaces = roundFunc.Curry()(2);
var roundedResults = numberList.Select(roundToTwoPlaces);

这里的问题是还有匿名委托(delegate),这使得柯里化(Currying)变得多余。事实上,匿名委托(delegate)一种柯里化(Currying)形式。

Func<double, double> roundToTwoPlaces = n => Math.Round(n, 2);
var roundedResults = numberList.Select(roundToTwoPlaces);

甚至只是

var roundedResults = numberList.Select(n => Math.Round(n, 2));

柯里化(Currying)是一种在给定特定函数式语言语法的情况下解决特定问题的方法。有了匿名委托(delegate)和 lambda 运算符,.NET 中的语法就简单多了。

关于C# lambda - curry 用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/520083/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com