Gauche の勉強メモ
ポール・グレアムさん著 On Lisp の flatten を Scheme で素直に書きなおしてみる。
;; flatten, On Lisp に載ってる Common Lisp Version (defun flatten (x) (labels ((rec (x acc) (cond ((null x) acc) ((atom x) (cons x acc)) (t (rec (car x) (rec (cdr x) acc)))))) (rec x nil)))
(flatten ‘(a (b c) d (e f))) ;; -> (a b c d e f)
は、Gauche では、下記のように書ける。
(atom? はデフォルトで定義されてないので、関数が一個増えちゃうけど)
(define (atom? obj) (and (not (pair? obj)) (not (null? obj))))
(define (flatten x) (define (rec x acc) (cond ((null? x) acc) ((atom? x) (cons x acc)) (else (rec (car x) (rec (cdr x) acc))))) (rec x '()))
もう一つのバージョンとして、
;; flatten を letrec で書きなおしてみた (define (flatten x) (letrec ((rec (lambda (a acc) (cond ((null? a) acc) ((atom? a) (cons a acc)) (else (rec (car a) (rec (cdr a) acc))))))) (rec x '())))
そして、素数夜曲: 女王陛下のLISP を読んでいたら、append とlist を使った実にスマートなバージョンが載っていた。(末尾再帰ではないが、やっていることが単純明快である。)
(define (flatten lst) (cond ((null? lst) '()) ((pair? lst) (append (flatten (car lst)) (flatten (cdr lst)))) (else (list lst))))
SN 2013/07/06 01:39:37
Archives > 20130705_Gauche_study_memo.html