Haskell ReplicateM IO

时间:2012-03-12 11:15:42

标签: haskell io parse-error replicate

我正在尝试创建一个允许用户输入字符串列表的函数。该函数采用长度并允许用户输入长度为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给出了解析错误。

1 个答案:

答案 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"]