我正在尝试创建一个允许用户输入字符串列表的函数。该函数采用长度并允许用户输入长度为1的行。然后检查每一行以确保它与原始行的长度相同。但是,我遇到了一些问题,我找不到解决办法。
问题在于我可以输入多于count-1行,并且长度未按我的预期计算..例如,如果我输入[“12”,“13”]然后[“121”, “13”]给出了错误,尽管长度相同!
read :: IO [Line]
read = do
line <- getLine
let count = length line
lines <- replicateM (count-1) $ do
line <- getLine
if length line /= count
then fail "too long or too short"
else return line
return $ line : lines
Line的类型为String。
readLn给出了解析错误。
答案 0 :(得分:5)
听起来我觉得你对将一行作为String
和读取/解析一行输入作为自定义类型之间的区别感到困惑。您正在使用getLine
,它始终返回用户键入的String
。比较:
Prelude> fmap length getLine
["12","13"]
11
Prelude> length "[\"12\",\"13\"]" -- explanation of the 11
11
Prelude> fmap length (readLn :: IO [String])
["12","13"]
2
Prelude> length ["12", "13"] -- explanation of the 2
2
如此处所示,您可能希望使用readLn
,它首先获取一行输入,然后使用read
进行解析。
-- defined in the Prelude
readLn = do
s <- getLine
return (read s)
如果我修改您的代码以包含下面的导入和定义:
import Control.Monad
type Line = [String]
...要拨打readLn
而不是getLine
,我就可以无误地输入文字行["12","13"]
和["121","13"]
。