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.
精彩评论