Lisp IF-THEN-ELSE Lambda Calc实现

时间:2012-11-25 02:06:01

标签: lisp lambda-calculus

我制作了这个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是“Less or Equal”的功能,它可以正常工作。所以当我像这样称呼IF-THEN-ELSE时(“六”和“两个”是教会号码)

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

作为输出我已经

"THIS" 
"THAT" 
"THIS"

正在调用我正在传递的两个函数。我怎样才能避免它只是作为输出“这个”?

我使用的每个函数都会发生这种情况,这是一个麻烦,因为我想在递归调用中使用IF-THEN-ELSE,所以只需要在IF-THEN-ELSE eval上调用一个函数。

任何帮助将不胜感激

感谢。

1 个答案:

答案 0 :(得分:1)

通过将print语句包装在lambda中来传递它们应该有效,但也许值得解释为什么这是必要的。

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

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

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

onetwo是教会编号。通过这样做,你在lambda演算中表达了你在普通lisp中的意思:

(if (>= 6 2) 
  1 
  2)

但我猜你的目标是:

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

(稍后更多关于为什么弄乱print可能会分散你的运动)

所以'真实'1有一个编码one的教会,我假设你已经定义了。这样,它可以应用到lambda抽象IF-THEN-ELSE - 就像

一样
(>= 6 2)

lisp world 中评估为TRUE,你的lambda演算实现相同,

((GEQ six) two)

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

(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演算中引入(print "hello")和其他“做东西”的代码可能没有太大帮助 - 微积分没有定义IO,并且仅限于评估lambda表达式。教会编码是一种将数字编码为 lambda术语的方法;没有简单而有意义的表达方式 带有副作用的语句这样的#'(lambda () (print "THIS"))作为lambda术语; if有效,但作为学术练习,最好只坚持评估事物并取回结果。

lisp本身怎么样? lisp中的(if cond then-expr else-expr)不是一个函数,因此then-expr的工作方式与预期的方式相同(即,else-expr或{{1}}中只有一个将被实际评估),因为它是< em>特殊形式。如果你要定义自己的,你需要一个(正如@wvxvw正确建议的那样)。但这是另一个话题。