S式を取り除くrember

5章もこれで最後だ。
つい先日、ラット lat の中からアトム a を取り除く関数 rember を書いた。今度は、この rember をS式のリスト l からS式 s を取り除くように書き直すと次のようになる。
(おっと、その前に equal? と eqlist? を mymodule.scm に加えておこう)

(use mymodule)

(define rember
  (lambda (s l)
    (cond
      ((null? l) (quote ()))
      ((atom? (car l))
      (cond
        ((equal? (car l) s) (cdr l))
        (else (cons (car l) (rember s (cdr l))))))
      (else
        (cond
          ((equal? (car l) s) (cdr l))
          (else (cons (car l) (rember s (cdr l)))))))))

(print (rember '(cup) '((coffee (cup)) tea (cup) and ((hick) cup))))
^o^ > gosh -I. rember2.scm
((coffee (cup)) tea and ((hick) cup))

これを簡単化せよ、と。まあ、難しくはない。equal? は任意のS式を比較できるんだから、(atom? (car l)) の条件は必要ない。というわけでこうなる。

(use mymodule)

(define rember
  (lambda (s l)
    (cond
      ((null? l) (quote ()))
      (else
        (cond
          ((equal? (car l) s) (cdr l))
          (else (cons (car l) (rember s (cdr l)))))))))

(print (rember '(cup) '((coffee (cup)) tea (cup) and ((hick) cup))))
^o^ > gosh -I. rember3.scm
((coffee (cup)) tea and ((hick) cup))

さて、まだ簡単化できる。cond が二重になっているのが冗長だから、ひとつにしてしまえばいい。

(use mymodule)

(define rember
  (lambda (s l)
    (cond
      ((null? l) (quote ()))
      ((equal? (car l) s) (cdr l))
      (else (cons (car l) (rember s (cdr l)))))))

(print (rember '(cup) '((coffee (cup)) tea (cup) and ((hick) cup))))

だいぶ簡単になった。うまく動くか試してみよう。

^o^ > gosh -I. rember4.scm
((coffee (cup)) tea and ((hick) cup))

OK!これで5章は終わり。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください