我有以下代码:
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,没有空格,我不明白我做错了什么。
答案 0 :(得分:11)
Haskell缩进版Wikibooks article的“if
- 内 - do
”部分对此进行了解释。
问题在于do
- desugarer,then
和else
行看起来像新的声明:
do { first thing
; if condition
; then foo
; else bar
; third thing }
缩进then
和else
行可以解决问题。
更新:由于此标记为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
糖并使用模式匹配而不是head
和tail
以及if-then-else
控制结构。非正式地,这里的>>=
表示“从bar...
包装器中取出IO
的输出并通过checkZero
运行,返回结果”。
答案 1 :(得分:8)
将then
和else
缩进一级。但事情可能会发生变化Conditionals and do
-notation。