keyがなかったらaconsして、なければalistを途中でぶった切ってkeyとvalueに置き換える、ということでわりと素直なつもり。
(use srfi-1) (define (assoc-store alist key val) (define (equal-key? ls) (equal? (car ls) key)) (if (find equal-key? alist) (receive (head tail) (span (complement equal-key?) alist) (append head (acons key val (cdr tail)))) (acons key val alist)))
(define alist '((hoge . 1) (foo . 2) (bar . 3) (baz . 4))) (assoc-store alist 'foo 5) ;; => ((hoge . 1) (foo . 5) (bar . 3) (baz . 4)) (assoc-store alist 'fuga 5) ;; => ((fuga . 5) (hoge . 1) (foo . 2) (bar . 3) (baz . 4)) (define alist2 '((hoge . 1) (hoge . 3))) (assoc-store alist2 'hoge 9) ;; => ((hoge . 9) (hoge . 3))
追記
これでいいか。(use srfi-1) (define (assoc-store alist key val) (receive (head tail) (span (^l (not (equal? (car l) key))) alist) (if (null? tail) (acons key val alist) (append head (acons key val (cdr tail))))))
追記
unfoldがあったかー。list処理はmap, fold, named-letの優先順位で候補を考えるけど、間でunfoldやpair-foldの存在を思い出すようにしよう。(それに共有構造ってこういう使い方もアリなのか)
0 件のコメント:
コメントを投稿