関数を用いた抽象化の補足 - ラムダ式 プログラミング論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式を使うプログラムに作り直す。
© Copyright 2024 ExpyDoc