問題2-17〜18

リストを操作する練習です。nilの扱いやリスト結合のやり方には、まだまだ慣れていません。
問題2-17は、リストの最後の要素を取り出すための手続きです。cdrを連発して、cdrがnilだったらそれが最後の要素なので、その構成物のcarを返します。

(define (last-pair list)
  (if (null? (cdr list))
      (car list)
      (last-pair (cdr list))))

(last-pair (list 23 72 149 34))

=>34

問題2-18は、リストの順番をひっくり返す手続きです。最後の要素が上手く結合できないなどの失敗がありましたが、上記のlast-pairと、最後の要素だけを取り除いたリストを返すremove-last手続きを自作して、以下のように実装しました。恐ろしく無駄な動きが多そうな感じですが、そのあたりについては後日考えてみたいと思います。

(define (remove-last list)
  (if (null? (cdr list))
      '()
      (cons (car list) (remove-last (cdr list)))))

(define (reverse list)
  (if (null? list)
      '()
      (cons (last-pair list)
            (reverse (remove-last list)))))

(reverse (list 1 4 9 16 25))

=>(25 16 9 4 1)

この問題2-18は結構泥沼にはまってしまったのですが、その過程で参考にしたid:higeponさんのエントリーを見て、いろいろと見習いたい点を見つけることができました。自分が何に悩んだか、どういう風に考え直したら上手くいったのか。そんなことを克明に書く習慣を身につけていけたらいいなと思っています。