在haskell工作,发现奇怪的行为,将其剥离为裸骨
本作品
a :: Bool
a = case True of
True -> True
False -> False
但是当我尝试
时b :: IO Bool
b = do
let b' = case True of
True -> True
False -> False
return b'
我得到了
ghci>:l test.hs
[1 of 1] Compiling Main ( test.hs, interpreted )
test.hs:16:14: parse error on input ‘->’
Failed, modules loaded: none.
所以我试试
c :: IO Bool
c = do
let c' = case True of
True -> True
False -> False
return c'
这很有效。
什么?为什么?在这种情况下,为什么我需要额外的缩进?我无法找到任何相关信息,可能是因为这些关键字在日常用语中非常简短。是否有一些规范可以解释这种行为?
答案 0 :(得分:10)
基本缩进规则实际上非常简单:
where
,let
,do
,case .. of
之后)记下下一个词开头的列(可能在下一行)棘手的例子:
1 + case x of
A -> 45 -- note where "A" starts
B -> 10 -- same indentation: another case branch
+ 2 -- more indented, so it's "10+2"
+ 10 -- less indented, so it's "1+(case ...)+10"
在你的情况下,
let b' = case True of
True -> True
False -> False
我们有两个嵌套块,一个用于let
,另一个用于case..of
。 let
块使用b'
列。 case..of
块尝试重用相同的列,但我们需要首先将规则应用于最外层的块。因此True -> ...
行实际上是let
块的新条目。这会触发解析错误。
答案 1 :(得分:7)
我没有从规范中得到准确的措辞,但是Wikibook page非常清楚地解释了这个问题。
它的工作原理很简单:支持通过单个let-group绑定多个变量,例如:
c = do
let c' = …
d = …
e = …
return c'
您的True -> …
和False -> …
被错误地解释为要绑定的其他变量。