Document

関数を用いた抽象化の補足
- ラムダ式 プログラミング論I
関数を用いた抽象化の補足 - ラムダ式 無名の関数定義(lambda式)
補助関数が有用な場合は多い →複数の定義手段
• 例:局所的な定義の手段: local式 (第8回)
• 今回: lambda式
– その場で関数(計算手順)を定義して使える。
– 典型的な利用:計算手順が再帰的でなく、ある関数
への引数として一度だけ必要な時。
文法:(lambda (引数1 ... 引数n) 式)
– 意味は以下の関数を返すlocal式と同様
(local ((define (a-new-name 引数1 ...引数n) 式))
a-new-name)
注:DrScheme利用時はlambda式が使える言語レベルにする。
無名関数(lambda式)の利用
ある数 x の平方が c より大きいかを判断する場合を考え
る。(条件 x2 > c の成立をテスト。以下では xが3で cが8)
• 大域的な関数としての定義例(例えば関数名squared>?)
定義例 (define (squared>? x c) (> (* x x) c))
利用例 (squared>? 3 8) 結果は true
• 定義を局所化した local式を使う例
(local ((define (sq>? x c) (> (* x x) c))) (sq>? 3 8))
• 無名の関数を作るlambda式を使う例
((lambda (x c) (> (* x x) c)) 3 8)
必要な(2引数の)計算手順をlambda式で書いて使っている
手順が再帰的でなく利用が一度だけなら名前は不要。
上記は説明のための例だが、典型的には、手順が再帰的
でなく、ある関数への引数として一度だけ必要な時に便利。
関数(演算)を引数にとる関数フィルタ
第7回例題2の関数 filter1 を例に考える: リスト alist
の要素(種類 X)を、比較対照のデータt(種類 T) と比較演
算 rel_opの結果によりふるいにかける(規約は一般化済)
;;filter1: (X T -> boolean) (listof X) T -> (listof X)
;;return a list of those Xs x on alist
;; for which (rel_op x t) evaluates to true
(define (filter1 rel_op alist t)
(cond
[(empty? alist) empty]
[else (cond
[(rel_op (first alist) t)
(cons (first alist)
(filter1 rel_op (rest alist) t))]
[else (filter1 rel_op (rest alist) t)])]))
rel_op に与える比較演算をlambda式で作ってみる
無名関数によるフィルタ
第7回課題1 では、リスト L中でその平方が c より大きい数
を抽出する関数 filter_ squared> を filter1を使い定
義したが、その際、条件 x2 > c の成立をテストする関数
squared>? を定義してfilter1 を使った。これを lambda式
とfilter1 を使い定義すると以下のようになる。
;;filter_squared>:(listof number) number -> (listof number)
(define (filter_squared> alon c)
(filter1 (lambda (x t) (> (* x x) t)) alon c))
• 参考:条件判定を大域的な関数として定義する例
(define (squared>? x t) (> (* x x) t))
(define (filter_squared> alon c) (filter1 squared>? alon c))
• 参考:局所的な関数として定義する(local式を使う)例
(define (filter_squared> alon c)
(local ((define (sq>? x t) (> (* x x) t)))
(filter1 sq>? alon c)))
演習 lambda式
1) ある数の立方がある別の数より大きいかを判断する
lambda式を書く。
2) ある数の3倍して返すlambda式を書く。
3) 第9回の課題1の2のクイックソートプログラムについ
て、構造体 AddressNote の nameフィールドを比較す
るlambda式を使うプログラムに作り直す。