gpt4 book ai didi

haskell - Haskell 中的 Let 与 Lambda

转载 作者:行者123 更新时间:2023-12-03 23:47:33 26 4
gpt4 key购买 nike

我正在阅读 Will Kurt 的“Get programming with Haskell”。在第 3 课关于词法作用域的结尾,作者写道:

Using a let expression and a lambda function aren’t exactly the same thing under the hood. For example, the following code will cause an error if you try to run it:

counter x = let x = x + 1 in let x = x + 1 in x

To prove that let and lambda aren’t identical, rewrite the counter function exactly as it is here, but use nested lambdas instead of let.

这是我的解决方案,它按我预期的那样工作:

counterLambda x = (\x -> (\x -> x) (x + 1)) (x + 1)
-- counterLambda 2 == 4

但是,正如作者所建议的,如果我在 ghci 中运行 counter 2,它会永远挂起(使用 GHC 8.8.3)。

幕后发生了什么?


PS:当我正确命名变量时,它会起作用。

counter x = let a = x + 1 in let b = a + 1 in b
-- counter 2 == 4

最佳答案

在 lambda 和 let 中,每个 x 都覆盖了之前的那个。区别在于阴影的范围。 lambda 参数的范围仅限于 lambda,但 let 绑定(bind)的范围是整个 let ... = ... in ... 结构,因此 let x = x + 1 根据 自身 定义 x,而 (\x -> x) (x + 1) 阴影 x 表示 未隐藏的 x。让我通过向每个 x 添加一个数字来演示每个实现的影子范围:

counterLambda x0 = (\x1 -> (\x2 -> (\x3 -> x3) x2) (x1 + 1)) (x0 + 1)

counter x0 = let x1 = x1 + 1 in let x2 = x2 + 1 in x2

现在应该清楚为什么它们不同了。在lambda版本中,x1被赋值为x0 + 1,而在let版本中,x1被赋值为x1 + 1,不会终止。

关于haskell - Haskell 中的 Let 与 Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61681918/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com