提问人:Elliott 提问时间:10/9/2023 更新时间:10/9/2023 访问量:79
整数输入数组:为什么使用 read 函数时会出现解析错误?
Input array of integers: Why is there a parse error when using the read function?
问:
我一直在尝试在业余时间学习 Haskell 的基础知识,但我一直坚持调试这个小程序,它从用户那里获取整数输入,将它们转换为 s 列表:Int
module Main where
------------------------------------------------------------
lines_to_words_impl :: [String] -> [String] -> [String]
lines_to_words_impl output_words input_lines =
if null input_lines then output_words
else lines_to_words_impl (output_words ++ (words (head input_lines))) (tail input_lines)
lines_to_words :: [String] -> [String]
lines_to_words input_lines =
lines_to_words_impl [] input_lines
------------------------------------------------------------
words_to_ints_impl :: [Int] -> [String] -> [Int]
words_to_ints_impl output_ints input_words =
if null input_words then output_ints
else words_to_ints_impl (output_ints ++ (read (head input_words))) (tail input_words)
words_to_ints :: [String] -> [Int]
words_to_ints input_words =
words_to_ints_impl [] input_words
------------------------------------------------------------
load_ints_from_input :: String -> [Int]
load_ints_from_input input =
words_to_ints (lines_to_words (lines input))
------------------------------------------------------------
main :: IO ()
main = do
-- Now, I just grab and try to print the first integer,
-- which is enough to cause the read/parse error:
user_input <- getContents
putStrLn (show (head (load_ints_from_input user_input)))
但是当我输入一些数字时,它总是提供相同的运行时错误:
Prelude.read:无解析
在过去的一个月里,在我的业余时间里,我一直被难住了。我唯一使用该函数的地方是第 19 行,它的输入是 of ,我们知道它是非空的,因为我们在 if 语句中的位置 - 它真的应该只是在 godbolt 链接中给出示例输入。据我所知,我正确地使用了 read 函数(参见 hoogle)来读取整数字符串并将其解析为 .read
head
input_words
7
Int
有人可以指出为什么会发生此解析错误吗?
答:
4赞
willeM_ Van Onsem
10/9/2023
#1
基本原因是 Haskell 认为您正在解析 s 列表,因为您使用:Int
output_ints ++ (read (head input_words))
所以 的类型应该是 ,你可以把它包装成一个单例列表:read (head input_words)
[Int]
output_ints ++ [read (head input_words)]
来解决问题。
但这可以通过以下方式更高效、更易读地完成:map
lines_to_words :: [String] -> [String]
lines_to_words = concatMap words
words_to_ints :: [String] -> [Int]
words_to_ints = map read
load_ints_from_input :: String -> [Int]
load_ints_from_input = words_to_ints . lines_to_words . lines
main :: IO ()
main = do
user_input <- getContents
print (head (load_ints_from_input user_input))
评论
3赞
lsmor
10/10/2023
@Elliott通知,不等同于 。实际上,后者永远不会编译,但前者会这样做,如果是一个字符串列表,每个字符串代表一个整数列表。不要那么相信 chatGPT ;)output_ints ++ (read (head input_words))
(output_ints ++ read) (head input_words)
input_words
1赞
willeM_ Van Onsem
10/10/2023
@Elliott:聊天机器人肯定有附加值,但需要小心:它实际上只是根据以前的单词和某个“上下文”来预测单词的东西。因此,这些机器人倾向于“幻觉”:仅仅因为一个句子经常出现在某个上下文中,它们就包含了该句子。即使上下文不同。
1赞
Cubic
10/10/2023
@Elliott虽然像 ChatGPT 这样的工具有时可以作为一种学习辅助工具,但它们经常是错误的。在这种情况下,你从 ChatGPT 那里得到的声明只是纯粹的胡说八道,恰好听起来足够合理,令人信服。使用此类工具时要非常小心。
评论
words
已经在换行符边界处中断了单词,所以你可以用它来代替和扔掉。lines
lines_to_words{,_impl}