关于if-then-else缩进的haskell中的奇怪错误

Dra*_*sha 7 haskell functional-programming indentation

我有以下代码:

foo :: Int -> [String] -> [(FilePath, Integer)] -> IO Int
foo _ [] _ = return 4
foo _ _ [] = return 5
foo n nameREs pretendentFilesWithSizes = do
  result <- (bar n (head nameREs) pretendentFilesWithSizes)
  if result == 0
  then return 0 --  <========================================== here is the error
  else foo n (tail nameREs) pretendentFilesWithSizes
Run Code Online (Sandbox Code Playgroud)

我在上面的评论的行上得到一个错误,错误是:

aaa.hs:56:2:
    parse error (possibly incorrect indentation)
Run Code Online (Sandbox Code Playgroud)

我正在使用emacs,没有空格,我不明白我做错了什么.

Tra*_*own 11

这可以在Wikibooks关于Haskell缩进的文章的" if-within- do"部分中解释.

问题是,对于do-desugarer,thenelse行看起来像新的语句:

do { first thing
   ; if condition
   ; then foo
   ; else bar
   ; third thing }
Run Code Online (Sandbox Code Playgroud)

缩进thenelse行将解决问题.

更新:由于这是标记的beginner,我还会注意到在Haskell中通常会认为类似下面的内容更为惯用:

foo :: Int -> [String] -> [(FilePath, Integer)] -> IO Int
foo _ [] _ = return 4
foo _ _ [] = return 5
foo n (r:rs) filesWithSizes = bar n r filesWithSizes >>= checkZero
  where
    checkZero :: Int -> IO Int
    checkZero 0 = return 0
    checkZero _ = foo n rs filesWithSizes
Run Code Online (Sandbox Code Playgroud)

这不正是同样的事情,你的foo,但它避免了do糖和使用模式匹配,而不是headtailif-then-else控制结构.非正式地,>>=这里说" bar...IO包装器中取出输出并运行它checkZero,返回结果".


Yas*_*aev 8

缩进thenelse更多地排列一级.但是事情可能会改变条件和do注释.