applyはリストを展開する (applyの使い方: Common-Lisp)
“apply”という関数の使い方が、イマイチわかりづらかったので、いろいろ調べたことをまとめておく。
(apply fn lst) — lst(リスト) に fn(関数) を適用する。
(1) アトムを引数にとる関数の場合
CL-USER> (apply #'+ '(1 2 3))
6
+ は、任意の数の引数(アトム)をとり、それらの和を返す。
‘(1 2 3) 全体に + が適用された。すなわち (+ 1 2 3) と同じ。
この場合、'(1 2 3) のリストが展開されて、+ が適用されている。
applyを使って次の関数を作る。
(defun sum (lst)
(apply #'+ lst))
この場合、次のように sum関数を使う。
CL-USER> (sum '(1 2 3))
6
ここで &rest を使って、可変長の引数を渡せるようにすると・・・、
(defun sum (&rest lst)
(apply #'+ lst))
次のように、リストではなく、個別の数字で引数を任意の数だけ渡せるようになる。
CL-USER> (sum 1 2 3)
6
&rest は、与えられた引数をリストにして、関数本体で処理されるようにする。
(2) リストを引数にする場合
1+ の場合を考えてみる。
1+ は、引数が数(アトム)の場合、その数に1を加算するが、数のリストの場合、
mapcar を使えば、リストの各要素に 1+ を適用できる。
CL-USER> (mapcar #'1+ '(1 2 3))
(2 3 4)
add1 という関数にすると・・・
(defun add1 (lst)
(mapcar #'1+ lst))
CL-USER> (add1 '(1 2 3))
(2 3 4)
&rest を使うと・・・
(defun add1 (&rest lst)
(mapcar #'1+ lst))
CL-USER> (add1 1 2 3 4 5))
(2 3 4 5 6)
(3) apply を組合せる
apply はリストを展開して 引数の関数に渡すから、次のようにしなければならない。
(apply #'mapcar #'1+ '((1 2 3))
関数にすると、次のようになる。
(defun add1 (lst)
(apply #'mapcar #'1+ lst))
この場合、次のようにリストを渡さねばならない。
CL-USER> (add1 '((1 2 3)))
(2 3 4)
applyはリストを展開して mapcar に渡すので、'(1 2 3) の形で mapcar に
渡さなければならないので、'((1 2 3)) でなければならない。
しかし、次のように &rest を使うと、引数を自動でリストにしてくれる。
(defun add1 (&rest lst)
(apply #'mapcar #'1+ lst))
この場合は、次のようにできる。
CL-USER> (add1 '(1 2 3))
(2 3 4)
カテゴリー: Lisp, memo
タグ: &rest, apply, clisp, common, common-lisp, Lisp, mapcar, rest
カウント: 141