2012-11-25 11 views
1

我做了這個IF-THEN-ELSE演算代碼Lisp的IF-THEN-ELSE LAMBDA計算器實現

(defvar IF-THEN-ELSE 
    #'(lambda(con) 
     #'(lambda(x) 
      #'(lambda(y) 
       #'(lambda(acc1) 
        #'(lambda (acc2) 
         (funcall (funcall (funcall (funcall con x) y) acc1) acc2)))))) 
) 

(defun IF-THEN-ELSEOP(c x y a1 a2) 
    (funcall (funcall (funcall (funcall (funcall IF-THEN-ELSE c) x) y) a1) a2) 
) 

這大於或等於運營商

(defvar GEQ 
    #'(lambda(p) 
     #'(lambda(q) 
       (funcall #'LEQOP q p))) 
) 

LEQOP是「少一個功能或相等「,它的工作正常。所以,當我打電話IF-THEN-ELSE這樣(「六個一」和「二」是教會號)

(if-then-elseop GEQ six two (print "THIS") (print "THAT")) 

作爲輸出我有

"THIS" 
"THAT" 
"THIS" 

,我正經過這兩個函數正在被呼叫。我怎樣才能避免它,以獲得只有作爲輸出「這個」?

這發生在我使用的每個函數上,這是一個麻煩,因爲我想在遞歸調用中使用IF-THEN-ELSE,所以只需要在IF-THEN-ELSE eval上調用一個函數。

任何幫助,將不勝感激

謝謝。

回答

1

通過將您的print聲明包裝在lambda中應該可行,但也許值得解釋爲什麼這是必要的。

您正在實施lambda演算。根據定義,微積分中的所有'事物'是高階函數。您的sixtwo以及您可能定義的任何其他教會數字也是高階函數。

IF-THEN-ELSE是一個lambda 抽象(也是一個高階函數,因爲它的'參數'也是函數)。因此,這將是有效的:

(if-then-elseop GEQ six two one two) 

onetwo是教會的數字。通過這樣做,你在演算表達你會以純LISP爲:

(if (>= 6 2) 
    1 
    2) 

但我猜你是瞄準爲:

(if (>= 6 2) 
    (print "this") 
    (print "that")) 

(更多關於以後爲什麼用print搞亂可能是分心你的鍛鍊)

所以,「真正的」 1有一個教堂編碼one,這I'me假設你定義。這樣一來,它可以應用到拉姆達抽象IF-THEN-ELSE - 以同樣的方式,

(>= 6 2) 

值爲TRUE在口齒不清世界,你演算執行相同的,

((GEQ six) two) 

將評估爲真的λ編碼,該編碼再次被編碼爲高階函數。

(defvar TRUE #'(lambda (x) #'(lambda (y) x))) 
(defvar FALSE #'(lambda (x) #'(lambda (y) y))) 

所以要記住,規則是你逝去的周圍,在演算找回一切都是功能

0 := λf.λx.x    
1 := λf.λx.f x 
2 := λf.λx.f (f x) 
3 := λf.λx.f (f (f x)) 
... and so on 

這是爲什麼,如果你這樣做:

(if-then-elseop GEQ six two 
    #'(lambda() (print "THIS")) 
    #'(lambda() (print "THAT"))) 

應該工作。 (排序,預讀)

(我會堅持的IF-THEN-ELSE忠實解釋,但:

(defvar IFTHENELSE 
    #'(lambda (p) 
    #'(lambda (a) 
     #'(lambda (b) (funcall (funcall p a) b))))) 

哪裏p是你的病情......)

作爲一個側面說明值得指出的是,在lambda演算中引入print和其他代碼可能沒有太大的幫助 - 微積分不定義IO,並且僅限於評估lambda表達式。教會編碼是將數字編碼爲lambda術語;沒有簡單而有意義的方式來表示具有副作用,例如(print "hello")作爲lambda術語的陳述 a 陳述; #'(lambda() (print "THIS"))的作品,但作爲一個學術活動,最好堅持只評估事情和取得成果。

lisp本身if in lisp不是函數,因此(if cond then-expr else-expr)按照您的預期工作(即,只有then-exprelse-expr將被實際評估),因爲它是特殊格式。如果你要定義你自己的,你需要一個(正如@wvxvw正確的建議)。但那是另一個話題。