Scheme修行 第13章 ホップ、スキップ、ジャンプ(その2)
letccの続きです。
ノート:
rember
remberでもaが不変なのでletrecを用いて再定義出来る。
> (rember 5 '(1 2 3 4 5 6 5 4 3 2 1)) (1 2 3 4 6 5 4 3 2 1) >
multiremberではないので最初の5だけが削除される。
rember-beyond-firstはあるアトム以降の要素を全て削除する。
remberでは探しているアトムを見つけるとcdrを返していたが、そこで空リストを返せば良い。
例を評価してみる。*1
> (let ((a 'roots) (lat '(noodles spaghetti spatzle bean-thread roots potatoes yam others rice))) (rember-beyond-first a lat)) (noodles spaghetti spatzle bean-thread) > (let ((lat '(noodles spaghetti spatzle bean-thread roots potatoes yam others rice))) (rember-beyond-first (quote others) lat)) (noodles spaghetti spatzle bean-thread roots potatoes yam) > (let ((a 'sweetthing) (lat '(noodles spaghetti spatzle bean-thread roots potatoes yam others rice))) (rember-beyond-first a lat)) (noodles spaghetti spatzle bean-thread roots potatoes yam others rice) > (let ((lat '(cookies chocolate mints caramel delight ginger snaps desserts chocolate mousse vanilla ice cream German chocolate cake more desserts gingerbreadman chocolate chip brownies))) (rember-beyond-first (quote desserts) lat)) (cookies chocolate mints caramel delight ginger snaps) >
アトムaが見つかればそこから先を返せば良いが、特殊な事情は
- 最後に見つかったaより先を返す。
- 最後まで見つからなかった時にはlat全体を返す。
内部関数を呼び出す時に結果のリストを足し込んで行く方法もあるが、consではリストは逆向きに出来てしまうので、最後にreverseを呼ぶ必要がある。
letccを用いるやり方はaが見つかる度に計算を振り出しに戻し、そこから再び計算を再開させる方法。
アトムaが見つかった時点で残りのlatについてRを適用させ、その結果を以てskipを呼ぶので、latの先頭からアトムaを見つけるまでに呼ばれた関数の戻り道は全てスキップされる。
rember-upto-lastは
- アトムaとリストlatを引数に取り
- リストを値とする関数
その値は
- latに内部関数Rを適用した値
- ここで内部関数Rは
- リストlatを引数に取り
- リストを値とする関数
- その値は
- latが空の場合、空リスト
- latの先頭要素がアトムaと同値の場合、latの残りにRを適用しその値を以てrember-upto-lastの値とする
- そうでない場合、latの先頭要素とlatの残りにRを適用した値を連結したリスト
letccは再帰適用の奥から一気に最初の呼び出しの値を決める為の仕組みとして使っているので関数定義の意味を解釈する時には目印程度に思っておけば良い。
例を評価してみる。
> (let ((a 'roots) (lat '(noodles spaghetti spatzle bean-thread roots potatoes yam others rice))) (rember-upto-last a lat)) (potatoes yam others rice) > (let ((a 'sweetthing) (lat '(noodles spaghetti spatzle bean-thread roots potatoes yam others rice))) (rember-upto-last a lat)) (noodles spaghetti spatzle bean-thread roots potatoes yam others rice) > (let ((a 'cookies) (lat '(cookies chocolate mints caramel delight ginger snaps desserts chocolate mousse vanilla ice cream German chocolate cake more cookies gingerbreadman chocolate chip brownies))) (rember-upto-last a lat)) (gingerbreadman chocolate chip brownies) >