linq 一个函数的形式项是什么,它可以用“折叠”来表示?

gopyfrb3  于 2022-12-06  发布在  其他
关注(0)|答案(3)|浏览(173)

我经常使用LINQ Aggregate运算符。本质上,它允许您通过对函数的最后一个计算值和序列的下一个元素重复应用函数来对序列“累加”函数。
例如:

int[] numbers = ...
int result = numbers.Aggregate(0, (result, next) => result + next * next);

将计算数组元素的平方和。
在谷歌上搜索之后,我发现函数式编程中的通用术语是"fold",这让我对可以写成折叠的函数产生了好奇,换句话说,就是f = fold op中的f
我认为可以用这个运算符计算的函数只需要满足(如果我错了,请纠正我):

f(x1, x2, ..., xn) = f(f(x1, x2, ..., xn-1), xn)

这处房产看起来很普通,应该有个特别的名字。有吗?

o2g1uqev

o2g1uqev1#

一个Iterated binary operation可能是你正在寻找的。
您还需要添加一些停止条件,如

f(x) = something
f(x1,x2) = something2

它们定义了一个二元运算f和另一个函数F,在我提供的链接中,用来处理当你到达f(x1,x2)时发生的事情。

6l7fqoea

6l7fqoea2#

为了澄清这个问题:“平方和”是一个特殊的函数,因为它具有这样的性质,即它可以用折叠泛函加上一个λ来表示,即

sumSq = fold ((result, next) => result + next * next) 0

哪些函数f具有此属性,其中dom f = { A tuples }ran f :: B
显然,由于折叠的力学,f是可折叠的陈述是Assert存在一个h :: A * B -> B,使得对于A中的任何n〉0,x1,...,xn,f ((x1,...xn)) = h (xn, f ((x1,...,xn-1)))
h存在的Assert与您的条件几乎是一样的

f((x1, x2, ..., xn)) = f((f((x1, x2, ..., xn-1)), xn))     (*)

所以你几乎是正确的;不同之处在于,您需要A=B,这比一般的fold可表达函数要严格一些。但更有问题的是,fold一般也需要一个起始值a,该值被设置为a = f nil。您的公式()的错误之处在于它假设h是f在对列表上的作用,但这只在h(x, a) = a时成立。也就是说,在平方和的例子中,你给Accumulate的初始值是0,当你添加它的时候,它是一个什么都不做的函数,但是有一些可折叠表达的函数,其中的起始值做了一些事情,在这种情况下,我们有一个不满足()的可折叠表达的函数。
例如,以下面这个可折叠表达的函数lengthPlusOne为例:

lengthPlusOne = fold  ((result, next) => result + 1) 1

一个月11个月1x,而是一个月12个月1x。
最后,让我们给予一个列表上的函数不能用fold表示的例子。假设我们有一个黑盒函数,并在这些输入上测试它:

f (1) = 1
f (1, 1) = 1    (1)
f (2, 1) = 1
f (1, 2, 1) = 2 (2)

这样一个关于元组(=有限列表)的函数显然是存在的(我们可以定义它具有上述输出,并且在任何其他列表上为零),但是它是不可折叠的,因为(1)隐含h(1,1)=1,而(2)隐含h(1,1)=2
我不知道是否有其他的术语比说'一个函数可表达为一个折叠'。也许一个(左/右)上下文无关的列表函数将是一个很好的方式来描述它?

xriantvc

xriantvc3#

在函数式编程中,fold用于聚合列表、数组、序列等集合上的结果。您对fold的表述不正确,这会导致混淆。正确的表述可以是:

fold f e [x1, x2, x3,..., xn] = f((...f(f(f(e, x1),x2),x3)...), xn)

f的要求实际上是非常宽松的。假设元素的类型是T,e的类型是U。所以函数f实际上有两个参数,第一个参数的类型是U,第二个参数的类型是T。并返回U类型的值(因为这个值将再次作为函数f的第一个参数提供)。我们有一个签名为f: U * T -> U的“accumulate”函数。因此,我认为没有一个正式的术语来描述这类函数。
在你的例子中,e = 0T = intU = int和你的lambda函数(result, next) => result + next * next有一个签名f: int * int -> int,它满足“可折叠”函数的条件。
如果你想知道,fold的另一个变体是foldBack,它以从xnx1的相反顺序累加结果:

foldBack f [x1, x2,..., xn] e = f(x1,f(x2,...,f(n,e)...))

foldfoldBack返回相同的结果时,满足f(x,y)= f(x,y)的交换函数有一些有趣的例子。关于fold本身,它是范畴论中退化的一个具体例子。你可以阅读更多关于退化here的内容。

相关问题