2010/03/22

TSS rember1*, let/cc, try

rember1*はThe Seasoned Schemerに何度も出てくる練習問題です。

例えば
(rember1* 'meat '((pasta meat) pasta (noodles meat sauce) meat tomatoes))
; -> ((pasta) pasta  (noodles meat sauce) meat tomatoes)
というようなものです。

The Seasoned Schemerでは、一般的な再帰やlet/ccを使った例が出てきますが、いまいちです。いまいち、というかすごくわかりにくいです。
取り合えず、以下のコードが14章にでてくるlet/ccとtryを使った例です。
; rember1*
(define rm
(lambda (a l oh)
(cond
((null? l)(oh (quote no)))
((atom? (car l))
(if (eq? (car l) a)
(cdr l)
(cons (car l)
(rm a (cdr l) oh))))
(else
(if (atom?
(let/cc oh
(rm a (car l) oh)))
(cons (car l)
(rm a (cdr l) oh))
(cons (rm a (car l) 0)
(cdr l)))))))
(let/cc Say
(rm 'noodles '((food) more (food)) Say))
; -> no
(let/cc oh
(rm 'a '(1 2 3 (4 5 (6)(7)) 8 (9 (10 (((((11 12 13) a))b c ) d)) e)) oh))
; -> (1 2 3 (4 5 (6) (7)) 8 (9 (10 (((((11 12 13))) b c) d)) e))
(define rember1*
(lambda (a l)
(if (atom? (let/cc oh (rm a l oh)))
l
(rm a l (quote ())))))
(rember1* 'noodles '((food) more (food)))
; -> ((food) more (food))
; again
(define rember1*
(lambda (a l)
(let ((new-l (let/cc oh (rm a l oh))))
(if (atom? new-l)
l
new-l))))
; again
(define rm
(lambda (a l oh)
(cond
((null? l)(oh (quote no)))
((atom? (car l))
(if (eq? (car l) a)
(cdr l)
(cons (car l)
(rm a (cdr l) oh))))
(else
(let ((new-car
(let/cc oh
(rm a (car l) oh))))
(if (atom? new-car)
(cons (car l)
(rm a (cdr l) oh))
(cons new-car (cdr l))))))))
; try
(define-syntax try
(syntax-rules ()
((try var a . b)
(let/cc success
(let/cc var (success a)) . b))))
; again
(define rember1*
(lambda (a l)
(try oh (rm a l oh) l)))
(rember1* 'noodles '((food) more (food)))
; -> ((food) more (food))
(rember1* 'a '(1 2 3 (4 5 (6)(7)) 8 (9 (10 (((((11 12 13) a))b c ) d)) e)))
; -> (1 2 3 (4 5 (6) (7)) 8 (9 (10 (((((11 12 13))) b c) d)) e))
view raw rember1star.scm hosted with ❤ by GitHub

0 件のコメント:

コメントを投稿