我在阅读缩进规则时偶然发现:
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]
实际上,概述部分也提到了这种行为(尽管无可否认,理解它所说的并不特别容易(:
每当包含布局列表的语法类别结束时,也会插入一个大括号;也就是说,如果在右大括号合法的地方遇到非法的词位,则插入右大括号。