Ошибка Haskell: ошибка синтаксического анализа при вводе `='

Характеристики

GHC 6.12.1

Mac OS X 10.6.4 x64

MacBook Pro

Проблема

У меня проблемы с использованием синтаксиса let. Следующий код отказывается компилироваться:

module Main where

main = let x = 1
        y = 2
        z = 3
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z

Я пробовал использовать табуляцию в y = 2 и z = 3 еще больше. Нет игральных костей.

(Нежелательные) решения

Единственный способ, которым я получил код для компиляции, - это либо

  1. Замена жестких табуляций пробелами.
  2. Замена предложения let предложением where.

person mcandre    schedule 09.08.2010    source источник
comment
никогда не используйте вкладки с haskell, всегда используйте пробелы. Вкладки в haskell определены как 8 пробелов, что намного больше, чем люди часто ожидают/устанавливают в своем редакторе, поэтому всегда рекомендуется использовать пробелы. Любой приличный редактор позволит вам сделать так, чтобы вкладки производили пробелы.   -  person Axman6    schedule 30.10.2010
comment
Я нашел это отличным наглядным пособием и отличным руководством по этому вопросу в целом: http://echo.rsmw.net/n00bfaq.html#visualaid   -  person Brandon    schedule 02.09.2011


Ответы (5)


Сайзан в #haskell объясняет, что назначения в выражении let должны выравниваться, а не сам let. Пока задания совпадают, можно использовать жесткие или программные вкладки.

Правильный код:

module Main where

main = let
        x = 1
        y = 2
        z = 3
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z
person mcandre    schedule 09.08.2010
comment
Я обнаружил, что привязки (x, y, z) должны быть выровнены по вертикали, в отличие от знаков присваивания (=) трех привязок, что может быть трудно увидеть в этом примере. - person ssanj; 30.01.2014

Вы просто не можете правильно управлять отступом с помощью вкладок, потому что размер вкладки не определен.

Поэтому не используйте вкладки в Haskell. Они злые.

person Neil Bartlett    schedule 09.08.2010
comment
Или, для вещей, которые должны иметь другой уровень отступа, используйте новую строку. Например, поместите let в одну строку и x = 1 в следующую. Тогда вкладки не проблема. - person yfeldblum; 09.08.2010
comment
Нил, позволю себе не согласиться (см. мой ответ). Парень из #haskell помог мне создать компилируемую версию с жесткими вкладками. На самом деле ответ Джастиса правильный. - person mcandre; 10.08.2010
comment
Я выучил свой урок трудным путем! Я знал, что вкладки ужасны, но все еще использовал их только потому, что раньше они никогда не доставляли мне проблем. Если вы похожи на меня, избавьте себя от большой головной боли в будущем и прислушайтесь к этому совету прямо сейчас! - person MasterMastic; 22.04.2014

Отступ для каждого объявления в блоке let должен быть одинаковым. Также хорошим тоном является отступ «in» и «let» на одном уровне. Например..

main = let x = 1
           y = 2
           z = 3
       in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z
person Don Stewart    schedule 09.08.2010
comment
Как мне это сделать с жесткими вкладками? - person mcandre; 09.08.2010
comment
Почему вы хотите использовать жесткие вкладки? Они вполне приемлемы для языков, не использующих отступы для обозначения значения, но они просто усложнят вам жизнь в таких языках, как Haskell или Python. Как будто они сейчас. - person jrockway; 09.08.2010
comment
Python отлично справляется с жесткими вкладками. Однажды у меня возникли проблемы с кодированием Python через веб-клиент SSH, потому что клиент не мог вставлять вкладки. Я использую жесткие вкладки, потому что ненавижу принудительно изменять отступы в чужом коде до моей предпочтительной ширины отступов. С жесткими вкладками такой проблемы нет, поскольку текстовые редакторы могут просматривать жесткие вкладки любой ширины. - person mcandre; 10.08.2010

Лично я ставлю точку с запятой в конце каждой строки

module Main where

main = let x = 1 ;
           y = 2 ;
           z = 3 
in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z
person Son    schedule 08.07.2012
comment
Это будет работать с точкой с запятой, но я не буду использовать ее, так как язык отлично работает с ней. Просто для отступа используйте пробелы вместо табуляции (или табуляции правильно). - person Jaider; 15.11.2012

Если вы настаиваете на символах TAB в исходном коде, компилируется следующее:

module Main where

main =
    let x = 1
        y = 2
        z = 3
    in putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z

где все начальные пробелы представляют собой одну или две клавиши TAB, а пробел между let и x = 1 также является клавишей TAB. Просмотрено в режиме списка vi, чтобы сделать TAB и концы строк явными:

module Main where$
$
main =$
^Ilet^Ix = 1$
^I^Iy = 2$
^I^Iz = 3$
^Iin putStrLn $ "X = " ++ show x ++ "\nY = " ++ show y ++ "\nZ = " ++ show z$

Ваша жизнь станет намного проще, а код красивее, если вы переключитесь на пробелы.

person Greg Bacon    schedule 09.08.2010
comment
Спасибо. Я не думаю, что хочу каждый раз помнить о переходе между let и x. Кроме того, любой код, который я публикую, скорее всего, вызовет ошибки, так как читатели решат, что там обычный пробел. - person mcandre; 10.08.2010