Scheme 4 Javaer-3.高阶函数

1.3  Formulating Abstractions with Higher-Order Procedures

教材有时候依照学生的基础。从0讲起;有时候给出一个大图,然后具体地逐一介绍。

本文或同学们写学习笔记时。要依照后者进行归纳。


函数,是对一些数的复合操作,并且不依赖特定的数。如
(define (cube x) (* x x x))

它不针对某个数如3,而是对全部的參数数据求其立方。

由此。它是对

(* 5 5 5)

(* x x x) ; 这里x为实參
的抽象,而(* 5 5 5)等则编写为函数的应用( cube 5)。

注意,函数cube仅仅是将数作为參数。假设可以将函数作为还有一个函数的參数,会是一种什么场面呢?

函数是第一阶元素

编程语言一般会对其元素的使用方式。做出一些限制。而受到的限制最少的元素属于第一阶(first-class)

第一阶元素拥有的特权包含:
    用变量命名
    作为函数的參数
    由函数返回
    (能够包括在数据结构中)
Java的基本类型和引用类型。都是第一阶元素。可是。函数在Scheme中如同其基本数据类型一样,完全然全地是第一阶元素
所以,当把函数作为參数、返回值来使用的时候,就有了更高阶的函数。操作函数的函数即为高阶函数


在数学中。序列求和的sigma (∑)记法/符号,就是一个样例。

无论f(x)是什么。高阶函数∑求和。

假定我们有3个详细的求和函数。

1)sum-integers求代数和(从a到b)

(define (sum-integersa b)

  (if (> ab)

      0

      (+ a(sum-integers (+ a 1) b))))

2)sum-cubes求立方和,

3)pi-sum依照公式

求出л/8.

(define (pi-sum a b)

  (if (> ab)

      0

      (+ (/ 1.0 (* a (+ a 2)))(pi-sum (+ a 4) b))))

如今考虑设计一个高阶函数,表达∑符号。显然,除了參数a。b外,还须要指定∑中的项和变化规律,我们以term描写叙述∑中的项,而next描写叙述依照变化规律得到的下一项。则

(define (sum term next  a b) ;我喜欢a、b挨着

  (if (> ab)

      0

      (+(term a)

         (sumterm next (next a) b))))

定义的sum为∑求和这一高阶函数。


函数作为參数

高阶函数sum中,term和next都是函数形參,类似C的函数指针。如果我们在sum基础上定义求代数和。就须要提供term和next将要绑定的函数。
代数和的term,是一个恒等函数(identity),next是一个自增函数。


(define (identity x) x)
(define (inc n) (+ n 1))
于是,不须要单独定义sum-integers。而是应用高阶函数sum。得到sum-integers
(define (sum-integers a b)
  (sum identity inc a b))
(sum-integers 1 10)
另外。对于一次性的小函数,使用lambda表达式很紧凑。(在这里不是要点)


函数作为返回

高阶函数sum的返回值是一个数,高阶函数强大之处。能够将某些函数作为输入,而又返回一个函数——函数转换。

(define (transf f)
    (lambda(a)(+ a (f a)) ) )


(define (square x)
    (* x x) )

((transf square) 2)

函数transf的作用是对函数f进行平移,其返回值是由lambda定义的匿名函数。当将匿名函数应用到2时。得到的是2+f(2)。

函数的參数问题

高阶函数transf处理作为參数的函数f时,将它视为仅仅有一个參数的函数,如函数应用(f a)所暗示的。

可是作为參数的f,并没有说明这一信息。对于两个參数的op
(define (op x y)
    (* x y) )
将它应用到transf中是不应该的。解释器对于(transf op)的输出,为什么不是一个错误?当然。进一步应用会出错。
((transf op) 5) ;要2个參数
((transf op) 1 5) ;要一个參数


原文地址:https://www.cnblogs.com/clnchanpin/p/6757526.html