【Scheme归纳】4 高阶函数

1、高阶函数的介绍

高阶函数的英文名称是Higher Order Function,它们是以函数为参数的函数。主要用于映射(mapping)、过滤(filtering)、归档(folding)和排序(sorting)表。高阶函数让程序更具模块性,让函数更加通用。

函数sort具有2个参数,一个是需要排序的表,另一个是定序(Ordering)函数。下面展示了按照大小将一个整数表正序排序。而<函数就是本例中函数的定序函数。

(sort‘(420 -130 138 983 0 298 783 -783) <)

;Value:(-783 -130 0 138 298 420 783 983)

通过灵活使用定序函数,我们可以写出更强大的函数。

(sort‘(783 298 -289 429 892 479 -197)

(lambda (x y) (< (modulo x 100)(modulo y 100))))

;Value:(-197 -289 429 479 783 492 892 298)

我们之前讲过,modulo函数用来求余。

Scheme并不区别过程和其他的数据结构,因此你可以通过将函数当作参数传递轻松的定义自己的高阶函数。而且Scheme并没有定义块结构的语法,因此使用lambda表达式作为一个块。

2、映射

映射是将同样的行为应用于表所有元素的过程。R5RS定义了两个映射过程:其一为返回转化后的表的map过程,另一为注重副作用的for-each过程。

map过程的格式如下:

(map procedurelist1 list2 …)

procedure是个与某个过程或lambda表达式相绑定的符号。作为参数的表的个数视procedure需要的参数而定。

(map+ ‘(1 3 5) ‘(2 4 6))

;Value:(3 7 11)

(map(lambda (x) (* x x)) ‘(1 2 3))

;Value:(1 4 9)

通过类比可以发现后者的lambda表达式相当于前者的+函数。只不过后者只有一个list,而前者有2个。如果想要像前者一样,让两个list中的元素一次相乘,除了用*外,也可以用lambda表达式。

(map(lambda (x y) (* x y)) ‘(1 2 3) ‘(2 4 6))

;Value:(2 8 18)

但是如果我们这样写:(map (lambda (x) (* x x)) ‘(1 2 3) ‘(1 3 5)),它并不会得出(1 4 9) (1 9 25)。

如果我们这样写:(map (lambda (x y) (* x x) (* y y)) ‘(1 2 3) ‘(1 3 5)),它得出的结果是(1 9 25),这是因为其只有一个返回值。但是(* x x)这一部分确实计算了。通过下面的例子我们可以确信这一点。

(map(lambda (x y) (let ((list1 (* x x)) (list2 (* y y)))

list1)) ‘(1 2 3) ‘(1 3 5))

;Value:(1 4 9)

(map(lambda (x y) (let ((list1 (* xx)) (list2 (* y y)))

list1 list2))‘(1 2 3) ‘(1 3 5))

;Value:(1 9 25)          这里同样是因为其只能有一个返回值。

而map函数最终的返回值以运算结果来判断。

(map- ‘(3 2 0) ‘(3 1 1 3))

;Value:(0 1 -1)

(map– ‘(3 2 0) ‘(3 1))

;Value:(0 1)

因为前者中list1中没有和list2中最后一个元素相对应的元素了,而后者中list2中没有和list1中最后一个元素相对应的元素。

(map(lambda (x y z) (* x x) (* y y) (* z z)) ‘(1 2) ‘(3 4 5) ‘(6 7 8 9))

;Value:(36 49)

而在这里例子中为什么最后的返回值不是(36 49 64 81),博主也不知道了,还请知道的网友留个回复。

for-each

for-each的格式与map一致,但是for-each并不返回一个具体的值,只是用于副作用。(副作用的解释)我们同样通过一个示例来展示。

(definesum 0)

;Value:sum

(for-each(lambda (x) (set! sum (+ sum x))) ‘(1 2 3 4))

;Unspecifiedreturn value

sum

;Value:10

如前所述,for-each并没有返回值。

3、过滤

尽管过滤函数并没有在R5RS中定义,但MIT-Scheme实现提供了keep-matching-items和delete-matching-item两个函数。注意item后加和不加s。

(keep-matching-items ‘(1 -2 3 -4 5)even?)

;Value: (-2 -4)

其中even?我们可以认为对应于上前文中sort函数的定序函数,当然,我们也可以用lambda来作为这个参数。

(keep-matching-items ‘(10 39 0 -100 76)(lambda (x) (<= 10 x 100)))

;Value: (10 39 76)

4、归档

同样在R5RS中没有定义归档函数,但MIT-Scheme提供了reduce等函数。

(reduce + 0 ‘(1 2 3 4))                 ;⇒  10

(reduce + 0 ‘(1 2))                     ;⇒  3

(reduce + 0 ‘(1))                       ;⇒ 1

(reduce + 0 ‘())                        ;⇒ 0

(reduce + 0 ‘(foo))                     ;⇒  foo

(reduce list ‘() ‘(1 2 3 4))            ;⇒  (((1 2) 3) 4)

(define (sqrt-sum-sq ls)

(sqrt (reduce + 0(map (lambda (x) (* x x)) ls))))

5、排序

同样在R5RS中没有定义排序函数,而在MIT-Scheme中提供了sort(实为merge-sort实现)和quick-sort函数。这个函数我们在前面展示过,下面我们用sort函数,lambda,tan函数和<来写一个以tan(x)的大小升序排列的函数。

(define(sort-tan ls)

(sort ls (lambda (x y) (< (sin x) (siny)))))

;Value:sort-tan

(sort-tan‘(1 2 3 4 5 6))

;Value:(5 4 6 3 1 2)

6、apply函数

apply函数将一个过程应用于一个表,也就是将表展开作为过程的参数。该函数具有任意多个参数,但首末参数必须分别是一个过程和一个表。

(applymax ‘(-1 2 -3))

;Value:2

(apply* 1 2 ‘(3 4 5))

;Value:120

时间: 2024-10-04 22:52:50

【Scheme归纳】4 高阶函数的相关文章

[Scheme入门]3 高阶函数

 1.高阶函数的介绍 高阶函数的英文名称是Higher Order Function,它们是以函数为参数的函数.主要用于映射(mapping).过滤(filtering).归档(folding)和排序(sorting)表.高阶函数让程序更具模块性,让函数更加通用. 函数sort具有2个参数,一个是需要排序的表,另一个是定序(Ordering)函数.下面展示了按照大小将一个整数表正序排序.而<函数就是本例中函数的定序函数. (sort'(420 -130 138 983 0 298 783 -

高阶函数之函数作为参数

SICP 1.3.1  Procedures as Arguments,说明高阶函数之函数作为参数的原因:若干个函数拥有相似的算法或代码结构,对此加以抽象. (define (sum-integers a b) (if (> a b) 0 (+ a (sum-integers (+ a 1) b)))) (define (pi-sum a b) (if (> a b) 0 (+ (/ 1.0 (* a (+ a 2))) (pi-sum (+ a 4) b)))) 于是: 清单1: (defi

Python高阶函数与函数装饰器-day4

上节回顾 高阶函数 闭包函数 函数装饰器 模块导入 一.上节回顾 Python2与Python3字符编码问题,不管你是初学者还是已经对Python的项目了如指掌了,都会犯一些编码上面的错误.我在这里简单归纳Python3和Python2各自的区别. 首先是Python3-->代码文件都是用utf-8来解释的.将代码和文件读到内存中就变成了Unicode,这也就是为什么Python只有encode没有decode了,因为内存中都将字符编码变成了Unicode,而Unicode是万国码,可以"

Python 学习笔记 -- 内嵌函数、闭包、匿名函数、高阶函数map、高阶函数filter、高阶函数reduce

1 #------------------------------内嵌函数------------------------------ 2 #内嵌函数就是在函数内部定义函数 3 #实例一 4 print("#------------------------------内嵌函数------------------------------") 5 def funOutOne(): 6 x = 5 7 def funIn(): 8 x = 3 9 print("My funOutO

js高阶函数

map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果: function pow(x) { return x * x; } var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81] reduce()把一个函数作用在这个Array的[x1, x2, x3...]上,这个函数必须接收两个

python 高阶函数

高阶函数也遵循函数即变量的形式 高阶函数的形式: 1.把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能) 如: def abc(): print('this is abc') def def(func): print(func) def(abc()) ====结果=======出来的是一个内存地址 <function agc at 0x00......> 高阶函数实例 import time def bar(): time.sleep(3) def test1

python 中的高阶函数

函数名其实就是指向函数的变量 >>> abs(-1) 1 >>> abs <built-in function abs> >>> a=abs >>> a(-1) 1 高阶函数:能接收函数做变量的函数 >>> def abc(x,y,f): ... return f(x)+f(y) ... >>> abc(-2,3,abs) 5 python中的内置高阶函数 map()函数和reduce(

Python高阶函数-闭包

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 在这里我们首先回忆一下python代码运行的时候遇到函数是怎么做的. 从python解释器开始执行之后,就在内存中开辟了一个空间 每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来. 但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心. 等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪

Python学习笔记八:文件操作(续),文件编码与解码,函数,递归,函数式编程介绍,高阶函数

文件操作(续) 获得文件句柄位置,f.tell(),从0开始,按字符数计数 f.read(5),读取5个字符 返回文件句柄到某位置,f.seek(0) 文件在编辑过程中改变编码,f.detech() 获取文件编码,f.encoding() 获取文件在内存中的编号,f.fileno() 获取文件终端类型(tty.打印机等),f.isatty() 获取文件名,f.name() 判断文件句柄是否可移动(tty等不可移动),f.seekable() 判断文件是否可读,f.readable() 判断文件是