странная ошибка в haskell относительно отступа if-then-else - PullRequest
7 голосов
/ 31 мая 2010

У меня есть следующий код:

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 ]

11 голосов
/ 31 мая 2010

Это объясняется в разделе "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, возвращая результат».

8 голосов
/ 31 мая 2010

Отступ then и else строк на один уровень больше. Однако вещи могут измениться Условные обозначения и do -обозначение .

...