开发者

strange error in haskell about indentation of if-then-else

I have the following code:

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

I get an error on the line with the c开发者_运维百科omment above, the error is:

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

I'm working with emacs, there's no spaces, and i do not understand what did i do wrong.


This is explained in the "if-within-do" section of the Wikibooks article on Haskell indentation.

The problem is that to the do-desugarer, the then and else lines look like new statements:

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

Indenting the then and else lines will solve the problem.

UPDATE: Since this is tagged beginner, I'll also note that something like the following would generally be considered more idiomatic in 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

This does exactly the same thing as your foo, but it avoids the do sugar and uses pattern matching instead of head and tail and the if-then-else control structure. Informally, the >>= here says "take the output of bar... out of its IO wrapper and run it through checkZero, returning the result".


Indent then and else lines one level more. However things may change Conditionals and do-notation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜