2016-08-15 2 views
2

私は互いに補完する2つの閉包を持っています。私はもう一方の面で定義したいと思います。例えば、別の閉包に関して閉包を定義する

(defun more-than (v) #'(lambda (x) (> x v))) 

CL-USER> (funcall (more-than 5) 7) 
T 
CL-USER> (funcall (more-than 5) 3) 
NIL 

に続き、我々は上記のクロージャを使用して、その補数、less-than-or-equalを定義したいと我々は機能more-thanが定義されていることを言うことができます。これは私の試みが今まで働いていないので、上記の閉鎖ほど簡単ではないようです。誰かが解決策を指摘することができますか、これが共通のパターンであるかどうかを教えてください(つまり、最初のクロージャとは独立した第2のクロージャを定義する代わりに)。ここで

は、私がコメントで述べたように、あなたは機能の補完を行うことCOMPLEMENTを使用することができます

;; compile time error 
(defun less-than-or-equal (v) 
    #'(lambda (x) #'(not (more-than v)))) 
;; returns nil for every comparison 
(defun less-than-or-equal (v) 
    #'(lambda (x) (not (more-than v)))) 
+2

どのように実装しようとしましたか?単純な解決策は動作するはずです: '(defun less-than-equal(v)(補数(more-v)))' – jkiiski

+0

ありがとう!私は '補完 'を見逃してしまって、誤って元のクロージャの定義を模倣しようとしました!それにもかかわらず、私はこれが「not」を使って達成できるのだろうかと思います。 –

答えて

7

を動作しませんでした私の試行の2つです:あなたは

(defun less-than-or-equal (v) 
    (complement (more-than v))) 

関数を呼び出して結果を否定するのではなく、を使用して、MORE-THANによって返された関数を無効にしようとしています。 Xはまったく使用されていません。それを修正するには、あなたがする必要があります

(defun less-than-or-equal (v) 
    ;; The #' is not necessary here 
    (lambda (x) (not (funcall (more-than v) x)))) 

しかし、COMPLEMENTを使用してより良いです。

+0

'COMPLEMENT'は基本的に2番目の関数で明示的に書いたものです。 – Barmar

+1

@Barmarはい、その結果の無名関数が呼び出されるたびにではなく、 'MORE-THAN'を1回だけ呼び出すというわずかな利点があります。もちろん、それを変数にバインドすることはできますが、 'COMPLEMENT'があなたのためにそれを行うときにはなぜ悩ましいのですか? – jkiiski

+0

ああ、そうです。より良い同値は '(let((mt(more-v)))(lambda(x)(not(funcall mt)x))' – Barmar