Haskell readLn нет ошибки разбора - PullRequest
9 голосов
/ 12 марта 2012

Эта функция позволяет пользователю вводить список строк. Функция принимает длину и позволяет пользователю вводить длину на 1 строку больше. Затем каждая строка проверяется на ту же длину, что и исходная строка. Код:

readme :: IO [Line]
readme = do
 line <- readLn
 let count = length line
 lines <- replicateM (count-1) $ do 
  line <- readLn
  if length line /= count 
  then fail "too long or too short"
  else return line 
 return $ line : lines

Линия имеет тип String.

Когда я пытаюсь запустить функцию и ввести .. скажем ["12", "13"], я получаю следующее: * Исключение: ошибка пользователя (Prelude.readIO: нет разбора) и я не могу понять почему, есть идеи?

Ответы [ 3 ]

8 голосов
/ 12 марта 2012

Это потому, что вы пытаетесь прочитать что-то с неправильным типом.

Вы говорите, что Line это String ака. [Char]. Однако вводимый вами текст имеет формат ["12", "13"], который выглядит так, как будто он должен иметь тип [Line], он же. [String] или [[Char]].

Вам нужно объяснить, что такое Line на самом деле . Если вы хотите, чтобы Line была строкой, тогда зачем вы вводите списки строк в терминале? Что-то не так с вашей логикой в ​​этом случае.

Если вам нужен метод для ввода квадратных матриц, вы можете вместо этого указать type Line = [Int] и использовать один из следующих форматов:

-- What you type at the terminal:
1 -2 3
4 5 6
6 7 8

-- How to read it in your program:
line <- (map read . words) `fmap` getLine

-- What you type at the terminal:
[1, -2, 3]
[4, 5, 6]
[6, 7, 8]

-- How to read it in your program:
line <- readLn

Если вы действительно хотите ввести строки, чтобы type Line = [Char] и каждый номер в списке ввода становился символом Unicode, что означает, что при вводе [97, 98, 99] в терминале вы получите строку "abc"

-- What you type at the terminal:
[97, 98, 99]
[100, 101, 102]
[103, 104, 105]

-- How to read it in your program:
line <- (map toEnum) `fmap` readLn
5 голосов
/ 12 марта 2012

Если вам нужна помощь, ваша программа принимает следующие данные:

*Main> readme
"abc"
"123"
"456"
["abc","123","456"]

Возможно, вы намеревались написать getLine вместо readLn, но без знания цели вашей программынемного трудно сказать.

При изменении на getLine программа принимает:

*Main> readme
abc
123
456
["abc","123","456"]
4 голосов
/ 12 марта 2012

read не очень удобен для пользователя и не видит ["12","13"] в виде строки.Он будет принимать "123" или ['1','2','3'] или даже "[\"12\",\"13\"]" - другими словами, строка должна быть записана так, как она будет в вашей программе.В этом случае вам не нужно использовать read, поскольку вы просто читаете String, поэтому замена readLn на getLine будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...