根据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版。
答案 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中实施了。