Это объясняется в разделе "if
-within- do
" статьи Wikibooks об отступе на Haskell.
Проблема в том, что для 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
, возвращая результат».