組み込みのappend関数を実装すると次のようになる。
(define my-append (lambda args (cond ((null? args) '()) ((null? (cdr args)) (car args)) (else (append2 (car args) (apply my-append (cdr args))))))) (define append2 (lambda (a b) (if (null? a) b (cons (car a) (append2 (cdr a) b)))))
append2は引数で受け取った2個のリストをつなげる関数。
my-appendで重要な点は、可変長引数argsが
- 空リスト
- 要素1個
- それ以外
のどれにマッチするか調べるところ。
上のように書くのは長くなるので、次のようにmatch構文を使うと簡単に書けるらしい。
(define my-append (lambda args (match args (() '()) ((a) a) ((a . b) (append2 a (apply my-append b))))))
match構文を使うには、事前に
(use util.match)
しとかないといけないらしい。
match構文は、
(match <式> (<パターン1> <<式>がパターン1にマッチしたときの値>) (<パターン2> <<式>がパターン2にマッチしたときの値>) ... (<パターンn> <<式>がパターンnにマッチしたときの値>))
ってな形をしてて、<パターンi>にはいろんな高度な方法があるらしい。
今んとこは
- ()が空リスト
- (a)が要素1個のリスト
- (a . b)が要素2個以上のリストまたはドット対
ってだけ覚えておこう。
使ってみて便利だなぁと思ったところは、パターンマッチングしつつ、名前を束縛できるところかな。