【程序设计】5.4 [一把抓] 迭代函数 *

 

5.4 迭代函数*

我们还可以用更基础的迭代函数来实现不用临时变量完成e的计算。

序列 A 的迭代函数 A.iterate@a(x,a) 有两个参数 x 和 a,先不管这里的 @a,简单地认为 @a 是函数名的一部分,即函数名就是 iterate@a。很快就会讲到这个 @。

作为循环函数,A.iterate@a(x,a) 将针对 A 的每个成员计算 x,在 x 中可以使用 ~ 和 #表示循环中的 A 的当前成员和序号,这和其它循环函数相同。不同的是,迭代函数中还提供了符号 ~~,用于表示上一轮循环中计算出的 x,还开始循环时,~~ 的初始值是参数 a。所有成员都循环后,返回每一轮计算出来的 ~~ 构成的序列,其长度和 A 相同。

没有 @a 的函数 A.iterate(x,a) 则定义为 A.iterate@a(x,a) 的最后一个成员,即不再把中间过程收集成序列,只保留最后的 ~~。

我们看几个例子:

1. A.iterate(~~+~,0)

初始 ~~ 是 0,每轮循环会在 ~~ 上加上当前成员 ~,最后就是所有成员合计,即 A.sum()。

2. A.iterate@a(~~+~,0)

@a 保留每轮计算结果,即从头到当前成员的累积值,相当于 A.([:0].sum())。

3. A.iterate(if(~~<~,~,~~),-inf())

inf()表示无穷大,-inf() 就是负无穷大,就是最小的数了。这个运算在每轮循环中,如果碰到比 ~~ 更大的当前成员 ~,就用 ~ 替代 ~~,最后计算结果是 A.max()。

4. A.iterate(if(~~>~,~,~~),inf())

这个和上一个类似,会计算出 A.min()。

5. A.iterate(if(~,~~+1,~~),0)

分析之后可以知道,它将计算出 A.count()。

看来,迭代函数是这些聚合函数的“母函数”,可以用迭代函数把聚合函数定义出来。很容易用迭代函数定义出一个序列成员连乘的运算:A.iterate(~~*~,1),阶乘运算就是一个特例情况:n.iterate(~~*~,1)。

实际上,A.(x) 也可以理解为 A.iterate(~~|[x],[]) 或者 A.iterate@a(x,null)。迭代函数确实是其它循环函数的“母函数”。

现在可以用一句计算e了:1+20.iterate@a(~~*~,1).sum(1/~),中间的迭代函数也将计算出一个阶乘值序列。

【程序设计】 前言及目录
【程序设计】5.3 [一把抓] 循环函数进阶
【程序设计】5.5 [一把抓] 定位选出