Scheme 4 Javaer-3.高階函數

1.3  Formulating Abstractions with Higher-Order Procedures

教材有時候依照學生的基礎。從0講起;有時候給出一個大圖,而後具體地逐一介紹。html

本文或同窗們寫學習筆記時。要依照後者進行概括。編程


函數,是對一些數的複合操做,而且不依賴特定的數。如
(define (cube x) (* x x x))數據結構

它不針對某個數如3,而是對所有的參數數據求其立方。編程語言

由此。它是對ide

(* 5 5 5)函數

(* x x x) ; 這裏x爲實參
的抽象,而(* 5 5 5)等則編寫爲函數的應用( cube 5)。學習

注意,函數cube僅僅是將數做爲參數。假設能夠將函數做爲還有一個函數的參數,會是一種什麼場面呢?spa

函數是第一階元素

編程語言通常會對其元素的使用方式。作出一些限制。而受到的限制最少的元素屬於第一階(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) ;要一個參數

相關文章
相關標籤/搜索