为什么我不应该混用制表符和空格?

Why shouldn't I mix tabs and spaces?

我经常读到我不应该在 Haskell 中混用制表符和空格,或者我根本不应该使用制表符。为什么?

问题是双重的。首先,Haskell 是缩进敏感的,例如以下代码无效:

example = (a, b)
  where
    a = "Hello"
     b = "World"

两个绑定都需要缩进相同数量的 spaces/tabs(参见 off-side rule)。虽然在这种情况下很明显,但它在下面的情况下相当隐藏,我用 · 表示 space,用 »:

表示制表符
example = (a, b)
··where
····a = "Hello"
»   b = "World"

如果编辑器将显示按 4 的倍数对齐的制表符,这将看起来像有效的 Haskell 代码。但事实并非如此。 Haskell 制表符按八的倍数对齐,因此代码将被解释为:

example = (a, b)
··where
····a = "Hello"
»       b = "World"

其次,如果您只使用选项卡,您最终可能会得到一个看起来不正确的布局。例如,如果选项卡显示六个或更多 space(在本例中为八个),则以下代码看起来是正确的:

example = (a, b)
»       where»  a = "Hello"
»       »       b = "World"

但是在另一个使用 4 spaces 的编辑器中它看起来不再正确了:

example = (a, b)
»   where»  a = "Hello"
»   »   b = "World"

不过,它仍然是正确的。但是,习惯了 spaces 的人可能会重新缩进 b' 与 spaces 的绑定并最终出现解析器错误。

如果您在整个代码中强制执行代码约定,确保仅在行首使用制表符并在 whereletdo 之后使用换行符您可以避免一些问题(参见 11). However, current releases of GHC warn about tabs by default, because they have been a source of many 过去的解析器错误,因此您可能也想摆脱它们。

另见