странная ошибка в haskell о добавлении отступа if-then-else

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

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, нет никаких пробелов, и я не понимаю то, что сделало я делаю неправильно.

7
задан Yasir Arsanukaev 31 May 2010 в 22:02
поделиться

2 ответа

Отступ then и else строк на один уровень больше. Однако все может измениться Conditionals и do-notation.

8
ответ дан 6 December 2019 в 09:58
поделиться

Это объясняется в разделе "if-within-do" статьи Wikibooks об отступах в Haskell.

Проблема в том, что для do-десуггеров строки then и else выглядят как новые утверждения:

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

Отступы в строках then и else решат проблему.

UPDATE: Поскольку эта статья помечена как 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, вернув результат".

11
ответ дан 6 December 2019 в 09:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: