违反if-then-else的Haskell缩进规则

时间:2017-09-10 22:12:31

标签: haskell

根据Haskell indentation rules,“代码是某个表达式的一部分,应该比该表达式的开头”进一步缩进。但是,我发现以下示例似乎违反了上述规则,编译时没有任何错误或警告:

someFunction :: Bool -> Int -> Int -> Int
someFunction condition a b = if condition
then a - b
      else a + b

这里我定义了一个函数someFunction,它的主体是if-then-else块。根据缩进规则,then块是第一行中相同表达式的一部分,因此它应该比前一行缩进。然而在我的例子中,第二行then从与第一行相同的列开始,这个例子编译。

我不确定这里发生了什么。我正在使用GHC 8.0.1版。

1 个答案:

答案 0 :(得分:7)

我有理由相信这是deliberate GHC variation on the indentation rule的神器。很好听!

GHC读这个

foo = do
  item
  if a
  then b
  else c
  item

作为

foo = do {
  item ;
  if a ;
  then b ;
  else c ;
  item }

应触发解析错误。

然而,这种情况非常普遍,以至于GHC开发人员在某一时刻决定允许在;then之前选择else。对if语法的这种更改使代码编译。

这意味着if变得“特殊”,因为它不必缩进更多,但只能与前一项一样多。在问题中发布的代码中,then与前一项一样缩进,因此在它之前有一个隐式的;,这使代码编译。

但是,我仍然会尽量避免这种“风格”,因为它很古怪。

(就个人而言,我不会将此特例添加到GHC。但无论如何,这都不是什么大问题。)

我现在注意到Wikibook提到这个变体是未来Haskell版本的“提案”。现在这已经过时了,从那时起就已经在GHC中实施了。