0

引数のない関数のリストと整数のリストの2つの引数を持つ関数をlispで書く必要があります。最初のリストの関数を 2 番目のリストの順序で評価する必要があります。私はそのような機能を試しました:

(defun z4(funs kols)
    (funcall (nth (first kols) funs))
    (z4 funs (rest kols))
)

しかし、funcallでエラーが発生しています

NIL は CONS 型ではありません。

どういう意味ですか?単純に呼び出すだけで同じエラーが発生します

(funcall (first funs))

だから私はそれが関数のリストから関数を取得することで何かを仮定します。関数のリストから関数 get を評価するにはどうすればよいですか?

4

2 に答える 2

5

再帰呼び出しごとに、kolsパラメーターが になるまでパラメーターを減らしますnil。再帰を終了する必要がある場合は、終了条件 (つまり、空のリスト) のテストを追加する必要がありkolsます。nil

(defun foo (funcs order)
  (unless (endp order)
    (funcall (nth (first order) funcs))
    (foo funcs (rest order))))

より読みやすい解決策を提案します (ANSI Common Lisp 標準では実装に末尾呼び出しの最適化を強制しないため、より好ましい解決策です):

(defun foo (funcs order)
  (loop for n in order do (funcall (nth n funcs))))

前の例では、戻り値ではなく、副作用のために関数を実行すると仮定しました。


編集 1

Vatine が指摘したように、nthと リストを使用してコレクションにランダム アクセスを提供するのはパフォーマンスによくないため、関数をリストではなくvector(1 次元のarray) に格納する価値があるかもしれません。したがって、 が関数の であると仮定するfuncsvector、関数は次のように定義できます。

(defun foo (funcs order)
  (loop for n in order do (funcall (aref funcs n))))

さらに、関数の配列が(用語集のエントリaref)である場合に置き換えることができます。前者の方が一般的ですが、実装によっては後者の方が高速な場合があります。svrefsimple vector

simple vectorいずれかを使用して関数を作成できます

(vector #'func-a #'func-b ...)

また

#(func-a func-b ...)

関数のsimple vectorは、関数を使用して作成することもできますが、キーワード引数が指定さmake-arrayれていない場合に限ります または.:adjustable:fill-pointernil

于 2013-01-26T13:35:20.327 に答える
4
'(#'a #'b #'c)

関数A、B、Cのリストではありません。これは次のとおりです。

((FUNCTION A) (FUNCTION B) (FUNCTION C))

上記は関数ではなく、最初の記号FUNCTIONと別の記号のリストです。

どちらかを使用

(list #'a #'b #'c)

また

'(a b c)
于 2013-01-26T14:15:39.743 に答える