exercise 3.25
調子いい感じ。(・・・問題はこの次な気もするが)
以下解答。
(define (assoc key records) (cond ((null? records) #f) ((equal? key (caar records)) (car records)) (else (assoc key (cdr records))))) (define (make-table) (list '*table*)) (define (lookup keys table) (let ((subtable (assoc (car keys) (cdr table)))) (if subtable (if (null? (cdr keys)) (cdr subtable) (lookup (cdr keys) subtable)) #f))) (define (insert! keys value table) (define (make-new-tables keys value) (if (null? (cdr keys)) (cons (car keys) value) (list (car keys) (make-new-tables (cdr keys) value)))) (let ((subtable (assoc (car keys) (cdr table)))) (if subtable (if (null? (cdr keys)) (set-cdr! subtable value) (insert! (cdr keys) value subtable)) (set-cdr! table (cons (make-new-tables keys value) (cdr table))))) 'ok)
とりあえずlookupはサクッと潰した。
insert!の方はキーが見つからなかった後どうするか考えて、結局めんどいのでmake-new-tablesとか適当な名前の関数を作った。
ちなみに某所の解答例では(パス掛かってたけどコピっていいのかなぁ・・・)
(define (insert! keylist value table) (let ((subtable (assoc (car keylist) (cdr table)))) (if subtable (if (null? (cdr keylist)) (set-cdr! subtable value) (insert! (cdr keylist) value subtable)) (set-cdr! table (cons (if (null? (cdr keylist)) (cons (car keylist) value) (let ((newtable (list (car keylist)))) (insert! (cdr keylist) value newtable) newtable)) (cdr table))))))
とやっていた。確かにnewtableは空だから再帰で渡してもうまいこといくなぁ、と感心した。しかしletの後に式を2つ書くのは何だか慣れない・・・他でもそんな感じだけど。
あとkahuaの方では、ややこしいテーブルを作らずにリストをそのままkeyとして渡してた・・・・。なるほど盲点だなぁ。(というかありなのかな、これ)