有人可以向我解释一下Scheme中的这个表达式将如何返回100吗?
(((lambda (f) ((lambda (g) (lambda (h) (f (g (h 4))))) double)) square) inc)
我知道它以某种方式分解为"(2 *(4 + 1))^ 2"但是对于我的生活,我无法弄清楚如何。
这是针对类似问题的考试。其中大约有6或7个,我们必须在大约1或2分钟内找到答案(因为它们只是测试的一部分)。除了努力学习之外,我们的教授没有提供任何帮助,但我完全不知道如何做到这些,更不用说快速了。
任何帮助将不胜感激!谢谢。
答案 0 :(得分:5)
让我们一步一步 - 注意一个好的缩进如何让一切变得更容易理解!
(((lambda (f) ; call outermost lambda, f is bound to square
((lambda (g) ; call mid lambda, g is bound to double
(lambda (h) ; return lambda, h is unbound
(f (g (h 4)))))
double))
square)
inc)
上述表达已减少到:
((lambda (h)
(square (double (h 4))))
inc)
现在我们最后调用最后一个lambda
,h
绑定到inc
,从而产生以下表达式:
(square (double (inc 4)))
=> 100
答案 1 :(得分:1)
看看你马上看到的表达式,大多数是运算符..调用的格式为:
(operator operands ...)
因此,您知道运算符是这样的:
((lambda (f)
((lambda (g)
(lambda (h)
(f (g (h 4)))))
double))
square)
唯一的操作数就是:
inc
当查看操作员时,您再次看到打开括号,这意味着它也是一个调用。新运算符将f
绑定到square
并执行一个绑定g
到double
的新调用,并且由于最后一个lambda
没有括号,所以返回是预期的函数/闭包/过程。所以我们可以替换绑定而不改变它的含义,在这种情况下你会得到:
(lambda (h)
(square (double (h 4))))
现在让我们再次点击(operator operand)
:
((lambda (h)
(square (double (h 4))))
inc)
您在此处看到h
已绑定到inc
。如果我们替换它,我们可以用程序体替换整个事物:
(square (double (inc 4))) ; ==> 100
当你看到((lambda ...) ...)
时,你正在看一个匿名程序立即被召唤。它与(something ...)
相同,它也是一个调用,但这里变量something
shoudl被评估为一个过程。围绕(((lambda ..
或((something ...
这些中的任何一个的额外括号应该告诉您该函数应该返回一个随后被调用的函数。这是标准的正确方案,但不是最常见的方案,所以只需要学会了解这些,因为它需要更多的关注时间。在自己编写代码时,请考虑使用绑定来清除代码:
(let ((helper (something a b c))))
(helper d))
而不是:
((something a b c) d)
即使这些在写作时看起来同样简单,但是当你在长时间停顿后再次看时,你会感谢自己。