英文:
Why am I getting a "Prelude.read: no parse" error when trying to print a list of integers in Haskell?
问题
我试图输入一个整数列表并将其打印出来,但是我得到了以下错误信息:Prelude.read: no parse。
以下是代码:
main = do
putStrLn "输入一个整数列表:"
input <- getLine
let xs = read input :: [Int]
putStr "输入的列表是:"
print xs
输入:
2 4 6 8
期望输出:
输入的列表是:2 4 6 8
实际输出:
输入的列表是:Sample: Prelude.read: no parse
英文:
I tried to input a list of integers and print it out but I'm getting this error instead:
Prelude.read: no parse
Here's the code:
main = do
putStrLn "Enter a list of integers:"
input <- getLine
let xs = read input :: [Int]
putStr "The entered list is: "
print xs
Input:
2 4 6 8
Expected output:
The entered list is: 2 4 6 8
Actual output:
The entered list is: Sample: Prelude.read: no parse
答案1
得分: 4
The problem is that the following expression fails:
ghci> read "1 2 3 4" :: [Int]
*** Exception: Prelude.read: no parse
The read parser for the type [Int] expects to read a string containing a list in valid Haskell syntax:
ghci> read "[1,2,3,4]" :: [Int]
[1,2,3,4]
and won't accept a space-separated list of integers. Reading a single integer still requires the single integer to be in valid Haskell format, but since this is just the usual way of writing an integer literal, it works as expected:
ghci> read "1" :: Int
1
So, what you can do is use the function words to break your string "1 2 3 4" into strings each containing a single integer:
ghci> words "1 2 3 4"
["1","2","3","4"]
and then map the read function over the resulting list of strings, one integer at a time:
ghci> map read (words "1 2 3 4") :: [Int]
[1,2,3,4]
The revised program:
main = do
putStrLn "Enter a list of integers:"
input <- getLine
let xs = map read (words input) :: [Int]
putStr "The entered list is: "
print xs
almost does what you want, except it prints the list out in Haskell syntax:
Enter a list of integers:
1 2 3 4
The entered list is: [1,2,3,4] <-- Haskell syntax for list
If you want to print the list the same way it was entered, you can replace print xs with:
putStrLn (unwords (map show xs))
Here, the expression unwords (map show xs) is the inverse of map read (words input), and puts the list back into the original string format.
英文:
The problem is that the following expression fails:
ghci> read "1 2 3 4" :: [Int]
*** Exception: Prelude.read: no parse
The read parser for the type [Int] expects to read a string containing a list in valid Haskell syntax:
ghci> read "[1,2,3,4]" :: [Int]
[1,2,3,4]
and won't accept a space-separated list of integers. Reading a single integer still requires the single integer to be in valid Haskell format, but since this is just the usual way of writing an integer literal, it works as expected:
ghci> read "1" :: Int
1
So, what you can do is use the function words to break your string "1 2 3 4" into strings each containing a single integer:
ghci> words "1 2 3 4"
["1","2","3","4"]
and then map the read function over the resulting list of strings, one integer at a time:
ghci> map read (words "1 2 3 4") :: [Int]
[1,2,3,4]
The revised program:
main = do
putStrLn "Enter a list of integers:"
input <- getLine
let xs = map read (words input) :: [Int]
putStr "The entered list is: "
print xs
almost does what you want, except it prints the list out in Haskell syntax:
Enter a list of integers:
1 2 3 4
The entered list is: [1,2,3,4] <-- Haskell syntax for list
If you want to print the list the same way it was entered, you can replace print xs with:
putStrLn (unwords (map show xs))
Here, the expression unwords (map show xs) is the inverse of map read (words input), and puts the list back into the original string format.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论