Lisp 这段代码的行为如何(funcall中的函数组合)
我在lisp中具有以下功能:Lisp 这段代码的行为如何(funcall中的函数组合),lisp,common-lisp,Lisp,Common Lisp,我在lisp中具有以下功能: (defun F(F) #'(lambda (n) (if (zerop n) (funcall F n) (1+ (funcall (F F) (1- n)))))) 如果我调用: (funcall (F #'(lambda (x) (+ 2 x))) 2) 我不明白为什么输出是4 提前感谢因为我们知道参数,我们可以简化函数中的if语句: (funcall (F #'(lambda (x) (+ 2 x)))
(defun F(F)
#'(lambda (n)
(if (zerop n)
(funcall F n)
(1+ (funcall (F F) (1- n))))))
如果我调用:
(funcall (F #'(lambda (x) (+ 2 x))) 2)
我不明白为什么输出是4
提前感谢因为我们知道参数,我们可以简化函数中的
if
语句:
(funcall (F #'(lambda (x) (+ 2 x))) 2)
(1+ (funcall (F #'(lambda (x) (+ 2 x))) 1))
(1+ (1+ (funcall #'(lambda (x) (+ 2 x)) 0)))
(1+ (1+ 2))
4
前两个转换将
(如果为false A B)
替换为B
,而第三个转换将(如果为true A B)
替换为A
,因为我们知道参数,所以可以简化函数中的if
语句:
(funcall (F #'(lambda (x) (+ 2 x))) 2)
(1+ (funcall (F #'(lambda (x) (+ 2 x))) 1))
(1+ (1+ (funcall #'(lambda (x) (+ 2 x)) 0)))
(1+ (1+ 2))
4
前两个转换将
(如果为false A B)
替换为B
,而第三个转换将(如果为true A B)
替换为A首先,解开这两个F
:
(defun foo (fun)
#'(lambda (n)
(if (zerop n)
(funcall fun n)
(1+ (funcall (foo fun) (1- n))))))
现在,你呼叫:
(funcall (foo #'(lambda (x) (+ 2 x))) 2)
我们可以给内部lambda一个名称,我称之为add-2
(funcall (foo #'add-2) 2)
(Foo#'add-2)
然后返回函数
(lambda (n)
(if (zerop n)
(funcall #'add-2 n) ; n is always 0 here
(1+ (funcall (foo #'add-2) (1- n)))))
使用2
调用它,它不是zerop
,因此它是:
(1+ (funcall (foo #'add-2) 1))
我们已经知道(foo#'add-2)
返回的内容,现在使用1
调用它,它仍然不是zerop
:
(1+ (1+ (funcall (foo #'add-2) 0)))
现在参数是0
,因此我们进入基本情况:
(1+ (1+ (funcall #'add-2 0)))
现在我们可以看到foo
创建了一个函数,该函数将n
添加到调用(fun 0)
的结果中。首先,解开这两个F
:
(defun foo (fun)
#'(lambda (n)
(if (zerop n)
(funcall fun n)
(1+ (funcall (foo fun) (1- n))))))
现在,你呼叫:
(funcall (foo #'(lambda (x) (+ 2 x))) 2)
我们可以给内部lambda一个名称,我称之为add-2
(funcall (foo #'add-2) 2)
(Foo#'add-2)
然后返回函数
(lambda (n)
(if (zerop n)
(funcall #'add-2 n) ; n is always 0 here
(1+ (funcall (foo #'add-2) (1- n)))))
使用2
调用它,它不是zerop
,因此它是:
(1+ (funcall (foo #'add-2) 1))
我们已经知道(foo#'add-2)
返回的内容,现在使用1
调用它,它仍然不是zerop
:
(1+ (1+ (funcall (foo #'add-2) 0)))
现在参数是0
,因此我们进入基本情况:
(1+ (1+ (funcall #'add-2 0)))
现在我们可以看到,foo
创建了一个函数,该函数将n
添加到调用(乐趣0)
的结果中。没有人知道这个函数中发生了什么?请耐心等待。人们通常需要几个小时才能做出响应,尤其是当标记不是[c#]或[java]。;-)有个问题,我可以把线(1+(funcall(F)(1-n))展开如下:(1+(funcall(F(+2x))(1-n)))。这是函数的组合吗?另外,我注意到参数和函数有相同的名称这有什么含义吗?你可能想继续读下去。没有人知道函数中发生了什么?请耐心等待。人们通常需要几个小时才能做出响应,尤其是当标记不是[c#]或[java]。;-)有个问题,我可以把线(1+(funcall(F)(1-n))展开如下:(1+(funcall(F(+2x))(1-n)))。这像是函数的组合吗?我注意到参数和函数有相同的名称,这有什么含义吗?你可能想继续读下去。所以,在(1+(funcall(F)(1-n‘‘‘‘‘)’))行中,在funcall(F)中,他再次调用自己,而不是参数。是吗?@LuisAlves:两者:-)它在它的参数上调用自己。你能解释一下他是如何知道第一个F对应于函数本身而不是参数的吗?我发现这是因为在LISP中,如果在复合形式中第一个元素(汽车)是一个符号,那么它必须作为函数进行评估。如果第一个元素不是符号,那么它必须是lambda表达式。谢谢我还添加了这个链接,并给出了更好的解释,因此,在(1+(funcall(F)(1-n‘‘‘‘)’))行中,在funcall(F)中,他再次调用了自己,而不是参数。是吗?@LuisAlves:两者:-)它在它的参数上调用自己。你能解释一下他是如何知道第一个F对应于函数本身而不是参数的吗?我发现这是因为在LISP中,如果在复合形式中第一个元素(汽车)是一个符号,那么它必须作为函数进行评估。如果第一个元素不是符号,那么它必须是lambda表达式。谢谢我还添加了这个链接,并提供了更好的解释