高阶函数:过程作为返回值
讲解如何编写返回过程的高阶函数,以 make-power 为例演示逐层抽象的过程。
我们已经见识过如何编写一个把另一个过程当作实参的过程。事实证明,反过来同样可以做到——我们可以创建一个返回过程的过程!返回过程是一种把抽象再推进一步的绝佳方式:我们不必直接创建过程,而是让程序替我们创建过程!根据我们给程序传入的不同实参,它可以创建出许多不同的过程。
示例:make-power
(我们其实并不是在制造电力。那是在滥用权力 ;)。)
假设我们要定义一个过程 sum-powers,它把 a 到 b 之间每个数取 n 次幂后再求和。我们已经有现成的 sum,抄录如下:
(define (sum f a b)
(if (> a b)
0
(+ (f a) (sum f (+ a 1) b))))
根据我们目前所学,它大概会是这样:
(define (sum-powers n a b)
(sum (lambda (x) (expt x n)) a b))
但如果创建一个新函数 make-power,给定一个幂次 n,返回一个接受数 x 并返回其 n 次幂的函数,会怎么样呢?它看起来像这样:
(define (make-power n)
(lambda (x) (expt x n)))
如我们之前指出的,lambda 返回的是函数。这意味着,如果把对 make-power 的调用定义为一个 lambda,它返回的就会是一个函数!于是我们现在可以这样做:
(define square (make-power 2))
(define cube (make-power 3))
我们还可以把 sum-powers 函数重写成这样:
(define (sum-powers n a b)
(sum (make-power n) a b))
再看看我们在抽象之路上走了多远:在本实验开始时,我们为每种求和都定义了不同的过程——sum-doubles、sum-squares 和 sum-cubes。
而现在,我们抽象出了求和本身,于是任意一种求和都可以用一行清晰的代码表达出来。
由 CS 61AS 课程团队开发,基于 Abelson 与 Sussman 所著《计算机程序的构造和解释》(Structure and Interpretation of Computer Programs)。