Let's start Scheme

2014-01-14

SRFI-1の紹介

(LISP Library 365参加エントリ)

SRFI-1の紹介。このSRFIを使ってないSchemerはいないんじゃないかなぁと思われるくらい有名なSRFI。内容は便利なリスト操作手続きをまとめたもの。

今回は、便利だけどあまり日の目を見ない手続きに焦点を当てて紹介する。題はSRFIの目次に対応している。

Constructors

list-tabulate
iotaを知っている人は多いと思うが、list-tabulateも同様にリストを構築する手続き。以下のように使える。
(list-tabulate 5 values) ;; => (0 1 2 3 4)
第一引数にリストの要素数を受け取り、第二引数にリストのn番目の要素を構築する手続きを受け取る。上記の例だとiotaの方が短い記述でかけるが、数値以外の要素を作りたい場合には便利になる。

Miscellaneous

append-reverse
append-reverse!
見れば分かるような気がするが、(append (reverse lis) tail)のシノニム。後者reverse!を使うので、注意が必要。
(append-reverse (list 1 2 3) 4) ;; => (3 2 1 . 4)

Fold, unfold & map

append-map
append-map!
append-reverseと似たようなのだが、(apply append (map f lis1 ...))をするもの。リスト内リストを操作しつつフラットにするのに便利。
(append-map values '((1) (2) (3))) ;; => (1 2 3)

filter-map
(filter values (map f lis ...))をするもの。fが#fを返すような場合に返されるリスト内から#fを取り除く。
(filter-map (lambda (n) (and (number? n) n)) '(1 a 2 b 3 c)) ;; => (1 2 3)
注意が必要なのは、fの戻り値がリストの要素になるということ、なので以下のようなものは悲しい結果になる。
(filter-map even? '(1 2 3 4 5 6)) ;; => (#t #t #t)

Deletion

delete-duplicates
delete-duplicates!
リスト内から重複するリストを削除する。
(delete-duplicates '(a a b b c c)) ;; => (a b c)
(delete-duplicates '((a b) (c d) (a b) (e f) (c d)) equal?) ;; => ((a b) (c d) (e f))

ここに列挙したのは僕が便利だと思うものだけである。他にも便利そうな手続きがあるので気になったら眺めて使ってみるといいかもしれない。

No comments:

Post a Comment