方案中的多个 lambda 嵌套?



谁能向我解释一下 Scheme 中的这个表达式将如何返回 100?

(((lambda (f) ((lambda (g) (lambda (h) (f (g (h 4))))) double)) square) inc)

我知道它以某种方式分解为"(2*(4+1))^2",但对于我的生活,我不知道如何。

这是针对有类似问题的考试。其中大约有 6 或 7 个,我们必须在大约 1 或 2 分钟内找到它们的答案(因为它们只是测试的 1 个部分)。我们的教授除了努力学习之外没有提供任何帮助,但我完全不知道如何做到这一点,更不用说快速了。

任何帮助将不胜感激!谢谢。

让我们一步一步地走 - 注意一个好的缩进如何使一切更容易理解!

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

现在我们最后调用最后一个lambdah绑定到inc,得到如下表达式:

(square (double (inc 4)))
=> 100

查看表达式,您马上看到其中大部分是运算符。调用的形式为:

(operator operands ...)

因此,您知道运算符是这样的:

((lambda (f)
((lambda (g)
(lambda (h)
(f (g (h 4)))))
double))
square)

唯一的操作数是这样的:

inc

查看运算符时,您再次看到左括号,这意味着它也是一个调用。新运算符将f绑定到square,并执行新的调用绑定gdouble并且由于最后一个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应该被计算为一个过程。(((lambda ..((something ...这两个方面多加括号应该告诉您该函数应返回随后调用的函数。这是标准正确的方案,但不是最常见的,所以只要学会意识到这些,因为它需要更多的几秒钟的注意力。在自己编写代码时,请考虑使用绑定明确这一点:

(let ((helper (something a b c))))
(helper d))

而不是:

((something a b c) d)

尽管这些在撰写本文时看起来同样简单,但当您长时间停顿后再次查看时,您也会感谢自己。

最新更新