1.3.1 函数作为形式参数使用

1.3.1 函数作为形式参数使用

考虑如下的三个程序:第一个计算从A到B的整数的和。
(define (sum-intergers a b)
   (if (> a b)
     0
     (+ a (sum-intergers (+ a 1) b))))

第二个计算从给定的范围的整数的立方的和。
(define (sum-cubes a b)
   (if (> a b)
     0
     (+ (cube a) (sum-cubes (+ a 1) b))))

第三个计算从给定的范围的整数的公式(1/a*(a+2))的和。
这个计算得到的值趋近于圆周率的八分之一。(非常慢地)
(define (sum-pi a b)
   (if (> a b)
     0
     (+ (/ 1.0 (* a (* a 2))) (sum-pi (+ a 4) b))))

这三个程序很明显地共享一个共同的模式。它们的大部分是
相同的,不同的,仅仅是程序的名称,A的函数被用来计算
求和的通项公式,提供A的下一个值的函数。在下面的这个
通用的模板上填入占位符处的值,我们能够生成上面的三个程序
中的任何一个。

这个模板如下:
(define (<name> a b)
    (if (> a b)
       0
        (+ (<term> a)
     (<name> (<next> a) b))))

这个共同的模式的存在是一个有力的证据。就是一个有用的
抽象方法正期望着来到我们的面前。 的确,数学家们在
很久以前就标识出这个系列求和的抽象来,并且提出了
一个西歌玛的概念。

西歌玛的概念的威力在于,它允许数学家们面对这个求和的
概念本身,而不仅仅是特定的求和。
例如,关于求和的公式化的通用的结果是独立于特定的序列
被求和的。

与此相似的是,作为一个程序的设计者,我们希望我们的
编程语言有足够的表达能力,让我们能够写一个程序就能
表达求和本身的这个概念,而不仅仅是写一个程序仅能够
计算特定的求和。在编程语言中,我们能够实现上述的模板
并把代替处的值变成形式参数。

(define (sum term a next b)
    (if (> a b)
       0
        (+ (term a)
     (sum term (next a) next b))))

值得注意的是,函数sum 有形式参数 四个,是
上下边界 a b,函数 term,next.
我们能够使用函数sum 像其它的函数一样。
例如:我们能够使用它(结合一个自增的函数)来定义函数sum-cube.
(define (inc n) (+ n 1))
(define (sum-cubes a b)
    (sum cube a inc b))

使用这个函数,我们能够计算从一到10的立方的和。
(sum-cubes 1 10)
3025
使用标识函数的辅助来计算通项,我们能够定义整数求和
的函数。

(define (identity x) x)
(define (sum-integers a b)
   (sum identity a inc b))

然后 我们能从一加到十。
(sum-integers 1 10)
55
我们也能用同样的方式定义 pi-sum.
(define (pi-sum a b )
  (define (pi-term x)
         (/ 1.0 (* x (+ x 2))))
  (define (pi-next x)
     (+ x 4))
  (sum pi-term a pi-next b))
 
使用这些程序,我们能够计算一个近似值(approximation)。
(* 8 (pi-sum 1 1000))
3.139592655589783

一旦我们有了sum这个函数,我们能像使用一块砖头一样
用它来公式化更多的概念。例如,a的定积分函数f 是在
a b 之间的使用公式  计算的近似值。

猜你喜欢

转载自blog.csdn.net/gggwfn1982/article/details/81412251
今日推荐