Scheme手習い 第3章 偉大なるCons(その2)
consを使った関数の続きです。
ノート:
firsts
関数firstsを解釈すると
- 空リストか空ではないリストを含むリストlに適用し、「要素としてのリスト各々の最初の要素だけからなるリスト」を意味する
- そのリストは:
- lが空リストの場合は空リストである
- lの最初の要素(これもリスト)の最初の要素に、lの残りのリストにfirstsを適用した結果を繋げたリストである
firstsの定義を評価してみる。
> (firsts '((a b) (c d) (e f))) (a c e) >
firstsとしては想定外の空リストあるいはアトムを含むリストの場合
> (firsts '((a b) () (e f))) . . mcar: expects argument of type <mutable-pair>; given () > (firsts '((a b) (c d) e f)) . . mcar: expects argument of type <mutable-pair>; given e >
carが取れないのでエラーとなる。
secondsは一瞬出て来るが定義が出て来ないので作ってみる。
(define seconds (lambda (l) (cond ((null? l) '()) (else (cons (car (cdr (car l))) (seconds (cdr l)))))))
lについては正しいリストが渡るものとし、特にエラーケースは考えない。
評価してみる。
> (seconds '((a b) (c d) (e f))) (b d f) >
insertR
insertの引数の名前としてnewは良いとして、oldは変ではないか?
関数insertRの最初の定義を解釈すると:
- アトムnewとoldと要素としてリストを含まないリストlatに適用し、「latと同じ要素を持つリストで最左のoldの次にnewが挿入された状態のリスト」を意味する(つもり)
- そのリストは:
- latが空リストの場合、空リストである
- latの先頭がoldと同じ場合、latの残りのリストである
- そうでない場合、latの先頭にlatの残りのリストのoldの右にnewを挿入した(つもりの)リストを繋いだリストである
この定義の動作を確認する。
> (let ((new 'topping) (old 'fudge) (lat '(ice cream with fudge for dessert))) (insertR new old lat)) (ice cream with for dessert) >
二番目の定義を解釈すると:
- アトムnewとoldと要素としてリストを含まないリストlatに適用し、「latと同じ要素を持つリストで最左のoldの次にnewが挿入された状態のリスト」を意味する(つもり)
- そのリストは:
- latが空リストの場合、空リストである
- latの先頭がoldと同じ場合、newとlatの残りのリストを繋いだリストである
- そうでない場合、latの先頭にlatの残りのリストのoldの右にnewを挿入した(つもりの)リストを繋いだリストである
この定義の動作を確認する。
> (let ((new 'topping) (old 'fudge) (lat '(ice cream with fudge for dessert))) (insertR new old lat)) (ice cream with topping for dessert) >
三番目の定義を解釈すると:
- アトムnewとoldと要素としてリストを含まないリストlatに適用し、「latと同じ要素を持つリストで最左のoldの次にnewが挿入された状態のリスト」を意味する
- そのリストは:
- latが空リストの場合、空リストである
- latの先頭がoldと同じ場合、oldとnewとlatの残りのリストを繋いだリストである
- そうでない場合、latの先頭にlatの残りのリストのoldの右にnewを挿入したリストを繋いだリストである
この定義の動作を確認する。
> (let ((new 'topping) (old 'fudge) (lat '(ice cream with fudge for dessert))) (insertR new old lat)) (ice cream with fudge topping for dessert) >
それまでに出て来た例も評価してみる。
> (let ((new 'jalapeño) (old 'and) (lat '(tacos tamales and salad))) (insertR new old lat)) (tacos tamales and jalapeño salad) > (let ((new 'e) (old 'd) (lat '(a b c d f g d h))) (insertR new old lat)) (a b c d e f g d h) >
insertL
insertLは例が無いので、insertRと同じ引数で評価して比較してみる。
> (let ((new 'topping) (old 'fudge) (lat '(ice cream with fudge for dessert))) (insertL new old lat)) (ice cream with topping fudge for dessert) >
fudgeとtoppingの順番が入れ替わっている。