1

我做了这个 IF-THEN-ELSE Lambda Calculus 代码

(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"

我传递的两个函数都被调用了。我怎样才能避免它以仅作为输出“THIS”获得?

我使用的每个函数都会发生这种情况,这很麻烦,因为我想在递归调用中使用 IF-THEN-ELSE,因此必须根据 IF-THEN-ELSE eval 调用一个函数。

任何帮助,将不胜感激

谢谢。

4

1 回答 1

1

print通过将它们包装在s 中来传递你的语句lambda应该可以工作,但也许值得解释一下为什么这是必要的。

您正在实现 lambda 演算。根据定义,微积分中的所有“事物”都是高阶函数。您sixtwo您可能定义的任何其他教堂数字也是高阶函数。

IF-THEN-ELSE是一个 lambda抽象(也是一个高阶函数,因为它的“参数”也是函数)。所以这将是有效的:

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

教会号码在哪里one,在哪里。two通过这样做,你在 lambda 演算中表达了你在普通 lisp 中的表达方式:

(if (>= 6 2) 
  1 
  2)

但我猜你的目标是:

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

(稍后会详细介绍为什么乱搞print可能会分散您的锻炼)

所以“真实”1有一个教堂编码one,我假设你已经定义了。这样,它就可以应用于lambda 抽象IF-THEN-ELSE- 以同样的方式

(>= 6 2)

在lisp 世界中评估为 TRUE ,您的 lambda 演算实现相同,

((GEQ six) two)

将评估为TRUE 的 lambda 编码,它再次被编码为高阶函数。

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

所以要记住的规则是,你在 lambda 演算中传递和返回的所有内容都是函数

 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……)

作为旁注,值得指出的是,print在 lambda 演算中引入和其他“做事”的代码可能并没有太大帮助 - 演算没有定义 IO,并且仅限于对 lambda 表达式的评估。Church 编码是将数字编码为lambda 项的一种方式;没有简单而有意义的方式来表示具有副作用的语句,例如(print "hello")lambda 项。#'(lambda () (print "THIS"))有效,但作为一项学术活动,最好坚持只评估事物并获得结果。

lisp 本身呢?ifin lisp 不是一个函数,因此(if cond then-expr else-expr)可以按照您期望的方式工作(也就是说,只有一个then-exprorelse-expr将实际被评估),因为它是一种特殊的形式。如果您要定义自己的,则需要一个(正如@wvxvw 正确建议的那样)。但这是另一个话题。

于 2012-11-30T16:25:27.550 回答