Что не так с этим отступом в Haskell?

В приведенном ниже коде Haskell я получаю сообщение об ошибке «ошибка синтаксического анализа при вводе« в »». Из того, что я прочитал, отступ, который я использовал, должен быть в порядке. На самом деле я успешно использую «let» и «in» с аналогичным отступом («let» выровнен с «in») в других частях моего кода. Какое правило я нарушил, из-за чего это «внутри» стало проблемой? Если я добавляю пробел перед «in» (делая его 1-пробелом дальше, чем «let»), он компилируется нормально.

runTests :: IO ()
runTests = do
             let results = fmap testLispExpr testLispText
                 resultStrings = fmap show results
                 putSeq (x:xs) = do putStrLn x
                                    putSeq xs
                 putSeq [] = return ()
             in putSeq resultStrings

Вся помощь приветствуется. Заранее спасибо.


person Community    schedule 11.02.2015    source источник
comment
Кстати, это эквивалентно runTests = mapM_ (print . testLispExpr) testLispText   -  person Ørjan Johansen    schedule 11.02.2015


Ответы (1)


Синтаксис let в блоках do немного забавен. Если вы хотите использовать in, вы должны сделать отступ справа от let. В качестве альтернативы вы можете вообще опустить in, и привязки let будут видны для остальной части блока do:

           do
             let ....
                 ....
             putSeq resultStrings
         --  ..... (more `do` statements)
         --  ^^ must all start on the same column

Редактировать

Как отмечает Ørjan Johansen, в данном случае do вообще не требуется, поскольку после let есть только одно выражение. Таким образом, другой вариант — опустить do, сохранив при этом ключевое слово in. И они также отмечают, что вы также можете написать это как

runTests = mapM (print . testListExpr) testLispText

и действительно сделать вещи чистыми.

person dfeuer    schedule 11.02.2015
comment
Третий вариант — пропустить do, так как есть только один оператор. - person Ørjan Johansen; 11.02.2015
comment
начал с малого (пропустить/опустить), закончил довольно подробным редактированием... извините за это. :) - person Will Ness; 16.04.2019