Почему я получаю ошибку синтаксического анализа при вводе «isFileEnd» в Haskell?

#haskell

Вопрос:

Ниже приведен мой код хаскелла.

 readTableFile :: String -gt; (Handle -gt; IO a) -gt; IO [a] readTableFile file func = do   fileHandle lt;- withFile file ReadMode (handle -gt; do   contents lt;- readDataFrom handle   putStr contents)  where readDataFrom fileHandle = do   isFileEnd lt;- hIsEOF fileHandle  if isFileEnd   then  return ("")  else  do  info lt;- hGetLine fileHandle  putStrLn $ func info  readDataFrom fileHandle  

Но я получаю ошибку:

 error: parse error on input ‘isFileEnd’  | 270 | isFileEnd lt;- hIsEOF fileHandle  | ^^^^^^^^^  

Я не знаю, почему. Пожалуйста, помогите мне

Комментарии:

1. похоже, проблема с отступом. Попробуйте сделать отступ в этой строке и во всех последующих, чтобы начало было дальше вправо, чем начало readDataFrom в предыдущей строке.

2. Не возвращайте ручку, данную вам изнутри withFile . К моменту завершения он уже будет закрыт (и поэтому недействителен) withFile . (Вы не совершаете этой ошибки… пока.)

Ответ №1:

У вас есть пара вещей, которые способствуют этому. Как отметил комментатор выше, когда вы получаете ошибки синтаксического анализа, которые выглядят удивительно, интервал всегда является первым, что нужно искать. Тем не менее, мы могли бы взглянуть на пару вещей, которые вносят свой вклад здесь:

  1. На readTableFile самом деле у вас всего одна строка длиной. У вас есть do блок, в котором единственное, что вы делаете, — это присваиваете fileHandle значение внутри withFile запущенной монады ввода-вывода. Помимо того факта, что withFile действие ввода-вывода будет возвращено вашим обработчиком (а не дескриптором файла, который может подразумеваться вашим именем), ваша функция на самом деле не возвращает действие ввода-вывода. Давайте немного приберемся:
 readTableFile file func = do  withFile file ReadMode (handle -gt; do   contents lt;- readDataFrom handle   putStr contents)  where readDataFrom fileHandle = do   isFileEnd lt;- hIsEOF fileHandle  [...]  
  1. Теперь мы возвращаем правильный тип, но вы все равно получите ошибку синтаксического анализа из isFileEnd lt;- задания. Теперь, когда мы все очистили, вы можете скомпилировать свой код, переместив его (и последующие строки) справа от первого символа readDataFrom объявления:
 where readDataFrom fileHandle = do   isFileEnd lt;- hIsEOF fileHandle  [...]  

Ваша работа на высшем уровне по-прежнему избыточна, но вы преодолеете свои непосредственные проблемы.

Комментарии:

1. Я бы подчеркнул, что на самом деле это только помогает вам преодолеть ваши непосредственные проблемы, и что ваш код, вероятно, все еще не будет делать то, что вы думаете, но, поскольку это, вероятно, домашнее задание, я бы предпочел использовать наименьший возможный толчок.