Haskell `let` 表达式中的名称捕获

name capture in Haskell `let` expression

我正在编写一个类似于此的函数:

f x = let
  x = ...
  in
    e

由于 Haskell 中的作用域规则,在 e 中对 x 的任何使用都将解析为 let 构造中 x 的定义。

为什么 Haskell 允许这样的事情? 编译器不应该拒绝这样的程序,告诉我们不能绑定与函数参数同名的值。

(这个例子可能很简单,但在现实世界中,变量具有与之相关的语义意义,很容易犯这样的错误)

您可以使用编译器标志启用针对此类名称隐藏的警告

-fwarn-name-shadowing

This option causes a warning to be emitted whenever an inner-scope value has the same name as an outer-scope value, i.e. the inner value shadows the outer one. This can catch typographical errors that turn into hard-to-find bugs, e.g., in the inadvertent capture of what would be a recursive call in f = ... let f = id in ... f ....

但是,使用 -Wall 进行编译更为常见,其中包含许多其他警告,可帮助您避免不良做法。