使用中缀运算符的do块内的缩进



我在阅读缩进规则时偶然发现:

y :: [Int]
y = do
c <- [4, 4, 4]
return c
++ [1]           -- line 5

因为

如果缩进相同的数量,则新项目开始(插入分号(;

我希望++前面(第5行(有一个;,它应该会给出解析错误,但似乎很好(示例(。这让我很困惑。

y :: [Int]
y = do{
;c <- [4, 4, 4]
;return c
;++ [1]}         -- I expected a ';' here and thus a parse error

我错过了什么?

您引用的段落以开头

非正式声明,

它实际上只是对正在发生的事情的快速概述,旨在给你一些直觉。正式规则见第10.3节布局。

在您的情况下,您的代码被更改为:

y :: [Int]
y = do 
{ c <- [4, 4, 4]
; return c
; ... {- we are here -}

最后一条规则实际上是:

L (<n> : ts) (m : ms) = ; : (L ts (m : ms)) if m = n 

然而,请注意,现在发出++将导致解析错误,因此此规则生效:

L (t : ts) (m : ms) = } : (L (t : ts) ms) if m∕ = 0 and parse-error(t)
(Note 5) 

因此,取而代之的是发出一个大括号,然后lexer正常进行。

最后,您的代码被解析为:

```haskell
y :: [Int]
y = do 
{ c <- [4, 4, 4]
; return c
; } ++ [1]

实际上,概述部分也提到了这种行为(尽管无可否认,理解它所说的并不特别容易(:

每当包含布局列表的语法类别结束时,也会插入一个大括号;也就是说,如果在右大括号合法的地方遇到非法的词位,则插入右大括号。

最新更新