haskell - Haskell 中的分组表达式是什么?

标签 haskell syntax indentation

indentation 上的 Haskell 文档中,它表示所有“所有分组的表达式必须完全对齐”。术语“分组表达式”是什么意思?为什么它们必须完全对齐?

最佳答案

文章中“分组表达式”的意思是必须对齐的一组事物中的一个成员!

我不认为这是一个很好的术语,因为很少有需要对齐的东西是技术表达式(它们大多是完整的声明)。

我还认为那篇文章开头列出的“黄金法则”并不是解释 Haskell 缩进要求的好方法。它说:

Code which is part of some expression should be indented further in than the beginning of that expression (even if the expression is not the leftmost element of the line).

然而,这实际上不是适用于所有 Haskell 表达式的通用规则。1

在 Haskell 中唯一重要的缩进总是在包含可变数量条目的“ block ”上下文中(wikibooks 文章将这些称为“组”)。例如:

  1. 一个let <decls> in <expr>表达式在 <decls> 中包含 1 个或多个声明部分
  2. 一个where子句引入 1 个或多个声明
  3. 一个instance定义的 where部分有零个或多个方法定义
  4. 一个do block 有 1 个或多个语句
  5. 一个case表达式有 1 个或多个案例(零个或多个 EmptyCase 扩展名)
  6. 等等等等

布局规则的目的是有一种方法来指示(对人类读者和编译器) block 中每个条目的确切扩展,以及 block 作为一个整体结束的位置,而不是使用空间布局比明确的标记符号。

“真正的”黄金法则是:这些 block /组中的所有条目必须始终从同一列开始2。如果一个条目本身跨越多行,那么这些条目的连续行必须严格更多缩进,而不是开始该 block 条目的列。

如果,通常情况下,您正在编写任何不是 block 中的条目的句法结构,那么维基教科书版本的“黄金法则”就是错误的;您可以将它分布在多行中,并根据需要缩进这些行,无需将连续行缩进到表达式开头以外的位置。3


1 正如我提到的,它很少应用于表达式;在我的脑海中,我认为 do block 中的语句是单个表达式(而不是 <- 绑定(bind))是唯一可以正式应用此规则的表达式。除 do 以外的所有其他 block 我现在能想到的 block 中的条目是句法结构,而不是简单的表达式。


2 或者您可以使用显式大括号和分号来分隔 block 的开始/结束以及 block 中每个条目的范围。在那种情况下,缩进/对齐根本不重要。


3 唯一的问题是您可能正在编写嵌套在外部条目 block 中的代码,并且您需要避免意外地与任何外部 block 的对齐要求发生冲突。这通常意味着表达式的所有部分都必须比 block 中最内层的封闭条目缩进更多,而不是这些部分必须比表达式本身的开头缩进更多。

关于haskell - Haskell 中的分组表达式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72992816/

相关文章:

haskell - 如果我重新开始编译,它会从中断的地方继续吗?

list - 出于效率原因,ghc 是否将仅使用一次的列表转换为生成器?

testing - 在 Ubuntu 上找不到模块 `Test.QuickCheck'

Swift 使方法参数可变?

c# - 在 C# 中编写延迟加载属性的简洁方法

python - 使用单行生成列表直到满足特定条件

if-statement - 为什么我们不在if/else的末尾加一个分号(;)呢?

indentation - Stylus 给我一个预期的 "indent",得到 "outdent",但我不知道为什么

Html 标签属性缩进最佳实践?

两个文本编辑器之间的 Python 缩进错误