2011-07-30 9 views
3

は私がリストx内のすべての要素は、プロパティaを持っているかどうかを確認する関数を記述しようとしているので、私は書いた:関数をlispで変数として使うにはどうしたらいいですか?

(defun check (a x) 
    (if (listp x) 
    (eval (cons 'and (mapcar #'a x))))) 

を、それは動作しません。 (基本的には、aを関数の名前、例えばblablablaとし、チェック機能の本体に#'aとしたいと思います。blablablaという関数を、aという関数の代わりに使いたいと思います。)上のコードでは、仕事。 Lispでは関数をプラグインできるはずだと思います。どうすれば修正できますか?

(それは愚かな質問かもしれませんので、それは、文字通りのLisp上の私の最初の日である;)。 とところで、私はLispworks 6.0個人的なバージョンを使用しています)

+0

あなたが達成したいかについて少し詳しく説明している場合に便利かもしれません。 – whoplisp

+0

この場合のEVAlの使用は間違いです。 –

+0

Common Lisp btw。すでにこの機能を提供しています。それはEVERYと呼ばれています。 –

答えて

6

ここでシャープな引用符の構文を使用する必要はありません。その目的は、可変位置に関数名を使用することですが、aはすでに変数です。 #'aの代わりにaと書いてください。

+0

それは働く。どうもありがとう。 –

3

あなたが使用することができますevalapplyを必要としません。 問題に:aを引数として指定するため、funcallが必要です。 (編集:この場合ではありません)引用することによって、関数aを参照するだけで、この関数のaは参照できません。

(defun check (a xs) 
    (if (listp xs) 
     (every #'identity (mapcar a 
           xs)))) 

より良い、loopを使用します。

(defun check (a xs) 
    (if (listp xs) 
     (loop for x in xs 
      always (funcall a x)))) 

ベスト、everyを使用します。

(defun check (a xs) 
    (if (listp xs) 
    (every a xs))) 
+2

この場合、 'funcall'は不要です。 'mapcar'は関数の指定子を最初の引数として受け取ります。したがって、' a'がシンボルと評価されると '(mapcar a ...)'はうまく動作します。 –

+2

また、マクロである 'and'を' apply'することはできません。代わりによく使われる 'every'という関数があります(ただし、この特定のケースでは' identity'のようなものと組み合わせる必要があります)。 –

+0

私はそれを試して、私は "エラー:そして、マクロの名前をFUNCTIONの悪い引数にする"だからこそ私はevalに変わった。 –

2

ここで私はあなたのチェック機能のようなものを書いています。私はそれをよりわかりやすい名前にしようとしました。

(defun are-all-elements-fullfilling-fun-p (fun ls) 
    (every #'identity (mapcar fun ls))) 

編集:注短く、より良い定義が

(defun are-all-elements-fullfilling-fun-p (fun ls) 
     (every fun ls))) 

であることを今の私たちは、この機能でそれを呼び出すようにしたいとしましょう。可能であれば宣言を使用する傾向にあることに注意してください。私は非常に頻繁に何かをねじ込み、コンパイラがエラーを把握することができればデバッグは簡単です。また、コードはより速く実行されます。

(defun is-even-p (n) 
    (declare (type number n)) 
    (the boolean (= 0 (mod n 2)))) 

あなたはここに「#を配置する必要があります。

(are-all-elements-fullfilling-fun-p #'is-even-p '(1 2 3 4)) 
(are-all-elements-fullfilling-fun-p #'is-even-p '(38 2 4)) 
+0

宣言をどこにでも追加することで、コードを変更するのが難しくなり、速度を向上させる保証はなく、状況を遅くする可能性もあります。それは勝つべき提案ではありません。 – Xach

+0

私は同意します。私が働いている問題については、しばしば役に立ちます。 – whoplisp

+0

私は本当にあなたの 'すべての要素が充実しているかどうか'関数がどのような方法でも 'EVERY'とは違うことが分かりません。あなたの定義は '# 'IDENTITY'と' MAPCAR'をスキップするよりもどのような状況で良いでしょうか? –

関連する問題