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

时间:2010-05-31 19:29:23

标签: 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

我在上面的注释中遇到错误,错误是:

aaa.hs:56:2:
    parse error (possibly incorrect indentation)

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

2 个答案:

答案 0 :(得分:11)

Haskell缩进版Wikibooks article的“if - 内 - do”部分对此进行了解释。

问题在于do - desugarer,thenelse行看起来像新的声明:

do { first thing
   ; if condition
   ; then foo
   ; else bar
   ; third thing }

缩进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

这与您的foo完全相同,但它避免使用do糖并使用模式匹配而不是headtail以及if-then-else控制结构。非正式地,这里的>>=表示“从bar...包装器中取出IO的输出并通过checkZero运行,返回结果”。

答案 1 :(得分:8)

thenelse缩进一级。但事情可能会发生变化Conditionals and do-notation