haskell - let 语句中的 case 语句需要什么缩进?

标签 haskell indentation do-notation

在 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'

这有效。

什么?为什么?在这种情况下,为什么我需要额外的缩进?我在这方面找不到任何东西,可能是因为这些关键字在日常语言中是如此简短和常见。是否有一些规范可以解释这种行为?

最佳答案

基本的缩进规则其实很简单:

  • 在开始一个 block 的关键字之后( whereletdocase .. of )记下下一个单词开始的列(可能在下一行)
  • 行缩进与 block
  • 中的新条目完全相同
  • 缩进更多的行继续上一个条目
  • 缩进小于该行的行结束该行
  • 之前的 block
  • 在嵌套 block 中,将规则应用于最外面的 block ,首先是

  • 棘手的例子:
    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
    

    我们有两个嵌套 block ,一个用于 let一个用于 case..of . let block 使用 b' 的列. case..of block 尝试重用同一列,但我们需要首先应用最外层 block 的规则。所以True -> ...行实际上是 let 的新条目堵塞。这会触发解析错误。

    关于haskell - let 语句中的 case 语句需要什么缩进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33004521/

    相关文章:

    haskell - Haskell Monads 中的 `let .. in do` 和 `<-` 表示法有什么区别?

    haskell - 通过 Nat-kind 重叠实例

    java - 漂亮的 HTML5 输出格式

    haskell - Haskell do block 中如何允许表达式

    Delphi:TPanel 和文本缩进

    javascript - 在大括号内时 vim 中的自动换行和缩进?

    Haskell 做符号边缘情况无法进行类型检查

    haskell - 函数的类型类实例

    Haskell:陷入 IO monad 困境

    haskell - 函数调用后秒差距意外字符