Haskell:将 lambda 表达式与绑定函数一起使用时的变量范围

发布于 2024-09-15 07:11:25 字数 443 浏览 6 评论 0原文

以下行按预期工作,但我有点担心为什么:

getLine >>= \x-> getLine >>= \y-> return [x, y]

考虑添加括号来确定 lambda 表达式的范围:

getLine >>= (\x-> getLine) >>= (\y-> return [x, y])

第二行是错误的,因为在 x 中使用时不在范围内>返回,我对此感到满意。让我担心的是,在第一行中,x 的范围似乎已经“泄漏”了。

这种“泄露”被认为是不好的做法吗?我很困惑它是如何保留在范围内的,并且在 \x -> > 之后没有立即丢失。 getLine 表达式。

The following line works as expected, but I am a little concerned why:

getLine >>= \x-> getLine >>= \y-> return [x, y]

Consider the addition of parenthesis to scope the lambda expressions:

getLine >>= (\x-> getLine) >>= (\y-> return [x, y])

The second line is errorneous because x is not in scope when used in the return, and I am happy with this. What concerns me this that in the first line the scope of x appears to have 'leaked' out.

Is this 'leaking' considered bad practice? I am confused as to how it has remained in scope and not been lost immediately after the \x -> getLine expression.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼眸印温柔 2024-09-22 07:11:25

如果您根据 haskell 的优先级规则正确地对第一行加上括号,您会得到:

getLine >>= (\x-> getLine >>= (\y-> return [x, y]))

这使得很明显第二个 lambda 位于第一个 lambda 之内,因此它访问第一个 lambda 的变量没有问题。

If you parenthesize your first line correctly according to haskell's precedence rules, you get:

getLine >>= (\x-> getLine >>= (\y-> return [x, y]))

This makes it obvious that the second lambda is inside the first, so there's no problem with it accessing the variables of the first lambda.

小苏打饼 2024-09-22 07:11:25

你的括号只是设置错误。正确的括号是

getLine >>= (\x -> getLine >>= (\y -> return [x, y]))

因此,x 当然是在主体中定义的。

请注意,此功能特别有用,因为您可以像这样格式化代码:

getLine >>= \x ->
getLine >>= \y ->
return [x, y]

这几乎

do
  x <- getLine
  y <- getLine
  return [x, y]

但没有任何特殊语法。

You parentheses are simply set wrong. The correct parentheses are

getLine >>= (\x -> getLine >>= (\y -> return [x, y]))

And therefore, x is of course defined in the body.

Note that this feature is particularly useful since you can format code like this:

getLine >>= \x ->
getLine >>= \y ->
return [x, y]

which is almost

do
  x <- getLine
  y <- getLine
  return [x, y]

but without any special syntax.

梦途 2024-09-22 07:11:25

Haskell 语法遵循“最大咀嚼”规则:每个语法元素都尽可能地扩展,直到进一步扩展会导致错误。由于它可以很好地将“\x ->”的范围一直扩展到末尾,因此它就是这样做的。

Haskell syntax follows the "maximal munch" rule: each syntax elements extends as far as it possibly can until extending it any further would result in an error. Since it works fine to extend the scope of the "\x ->" all the way to the end, that's what it does.

獨角戲 2024-09-22 07:11:25

return 表达式中对 x 的引用称为 关闭。这是函数式编程语言的典型特征。在像 Haskell 这样的纯函数式编程语言中,没有理由担心。这是一个非常好的功能。在“混合”函数式编程语言(例如 F#(以及如今的 C#))中,闭包有时确实会导致意外行为。

The reference to x in the return expression is known as a closure. It's a typical feature of functional programming languages. In a pure functional programming language, like Haskell, there is no cause for concern. It's a very nice feature. In 'hybrid' functional programming languages like F# (and C# these days), closures can indeed result in unexpected behavior sometimes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文