高階函數的英文名稱是Higher Order Function,它們是以函數爲參數的函數。主要用於映射(mapping)、過濾(filtering)、歸檔(folding)和排序(sorting)表。高階函數讓程序更具模塊性,讓函數更加通用。markdown
函數sort具備2個參數,一個是須要排序的表,另外一個是定序(Ordering)函數。下面展現了按照大小將一個整數表正序排序。而<函數就是本例中函數的定序函數。數據結構
(sort‘(420 -130 138 983 0298 783 -783) <)
;Value:(-783 -130 0 138 298 420 783 983)
經過靈活使用定序函數,咱們能夠寫出更強大的函數。app
(sort‘(783 298 -289 429 892479 -197) (lambda(x y) (< (modulo x 100)(modulo y 100))))
;Value:(-197 -289 429 479 783 492 892 298)
咱們以前講過,modulo函數用來求餘。函數
Scheme並不區別過程和其餘的數據結構,所以你能夠經過將函數看成參數傳遞輕鬆的定義本身的高階函數。並且Scheme並無定義塊結構的語法,所以使用lambda表達式做爲一個塊。ui
映射是將一樣的行爲應用於表全部元素的過程。R5RS定義了兩個映射過程:其一爲返回轉化後的表的map過程,另外一爲注重反作用的for-each過程。spa
map過程的格式以下:.net
(map procedurelist1 list2…)
procedure是個與某個過程或lambda表達式相綁定的符號。做爲參數的表的個數視procedure須要的參數而定。code
(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表達式。server
(map(lambda (x y) (* x y))‘(1 2 3)‘(2 4 6))
;Value:(2 8 18)
可是若是咱們這樣寫:blog
(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 925) 這裏一樣是由於其只能有一個返回值。
而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 78 9))
;Value:(36 49)
而在這裏例子中爲何最後的返回值不是(36 49 64 81),博主也不知道了,還請知道的網友留個回覆。
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並無返回值。
儘管過濾函數並無在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)
一樣在R5RS中沒有定義歸檔函數,但MIT-Scheme提供了reduce等函數。
(reduce + 0 '(1 2 34)) ;⇒ 10
(reduce + 0 '(12)) ;⇒ 3
(reduce + 0'(1)) ;⇒ 1
(reduce + 0'()) ;⇒ 0
(reduce + 0'(foo)) ;⇒ foo
(reduce list '() '(1 2 34)) ;⇒ (((1 2) 3) 4)
(define (sqrt-sum-sq ls) (sqrt (reduce + 0(map (lambda (x) (* xx)) ls))))
一樣在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)
apply函數將一個過程應用於一個表,也就是將表展開做爲過程的參數。該函數具備任意多個參數,但首末參數必須分別是一個過程和一個表。
(applymax‘(-1 2 -3))
;Value:2
(apply* 1 2‘(3 4 5))
;Value:120
感謝訪問,但願對您有所幫助。 歡迎關注或收藏、評論或點贊。
爲使本文獲得斧正和提問,轉載請註明出處:
http://blog.csdn.net/nomasp