Haskell:将 lambda 表达式与绑定函数一起使用时的变量范围
以下行按预期工作,但我有点担心为什么:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您根据 haskell 的优先级规则正确地对第一行加上括号,您会得到:
这使得很明显第二个 lambda 位于第一个 lambda 之内,因此它访问第一个 lambda 的变量没有问题。
If you parenthesize your first line correctly according to haskell's precedence rules, you get:
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.
你的括号只是设置错误。正确的括号是
因此,
x
当然是在主体中定义的。请注意,此功能特别有用,因为您可以像这样格式化代码:
这几乎
但没有任何特殊语法。
You parentheses are simply set wrong. The correct parentheses are
And therefore,
x
is of course defined in the body.Note that this feature is particularly useful since you can format code like this:
which is almost
but without any special syntax.
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.return
表达式中对x
的引用称为 关闭。这是函数式编程语言的典型特征。在像 Haskell 这样的纯函数式编程语言中,没有理由担心。这是一个非常好的功能。在“混合”函数式编程语言(例如 F#(以及如今的 C#))中,闭包有时确实会导致意外行为。The reference to
x
in thereturn
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.