Haskell readLn没有解析错误

时间:2012-03-12 12:56:50

标签: parsing haskell io

此功能允许用户输入字符串列表。该函数采用长度并允许用户输入长度为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

Line的类型为String。

当我尝试运行该函数并输入时..说[“12”,“13”]我得到以下内容: * 异常:用户错误(Prelude.readIO:无解析)和我无法弄清楚为什么,任何想法?

3 个答案:

答案 0 :(得分:8)

这是因为你试图阅读错误类型的东西。

你说LineString又名。 [Char]。但是,您输入的输入格式为["12", "13"],看起来应该具有类型[Line],aka。 [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

答案 1 :(得分:5)

如果有任何帮助,您的程序会接受以下输入:

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

你可能打算写getLine而不是readLn,但如果不知道你的程序的目的,这有点难以辨别。

更改为getLine,程序接受:

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

答案 2 :(得分:4)

read不是非常用户友好,并且它不会将["12","13"]视为字符串。它会接受"123"['1','2','3']甚至"[\"12\",\"13\"]" - 换句话说,字符串必须像在程序中一样编写。在这种情况下,您不需要使用read,因为您只是在阅读String,因此使用readLn替换getLine会有效。