将n行读入[String]

时间:2012-04-23 18:06:41

标签: haskell

我正在尝试将n行内容读入字符串列表。我已尝试过以下代码的几种变体,但没有任何效果。

main = do
  input <- getLine
  inputs <- mapM getLine [1..read input]
  print $ length input

这会引发以下错误:

Couldn't match expected type `a0 -> IO b0'
                with actual type `IO String'
    In the first argument of `mapM', namely `getLine'
    In a stmt of a 'do' block: inputs <- mapM getLine [1 .. read input]
    In the expression:
      do { input <- getLine;
           inputs <- mapM getLine [1 .. read input];
           print $ length input }

main = do
  input <- getLine
  let inputs = map getLine [1..read input]
  print $ length input

引发

 Couldn't match expected type `a0 -> b0'
                with actual type `IO String'
    In the first argument of `map', namely `getLine'
    In the expression: map getLine [1 .. read input]
    In an equation for `inputs': inputs = map getLine [1 .. read input]

我该怎么做?

2 个答案:

答案 0 :(得分:47)

使用Control.Monad中的replicateM

main = do
  input <- getLine
  inputs <- replicateM (read input) getLine
  print $ length inputs

本着给人一条鱼/教人钓鱼的精神:你可以通过搜索Hoogle找到自己。

你有:

  • 执行IO String
  • 类型的操作
  • 多次执行该操作(类型Int

你想:

  • IO [String]
  • 类型的操作

所以你可以search Hoogle for (IO String) -> Int -> (IO [String])replicateM是第一次点击。

答案 1 :(得分:1)

另一种可以执行此操作的方法是使用纯复制和sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) 工具。让我们先说我们会要求计数,然后要求那么多整数在终端上打印出来。

sumCountManyData :: IO ()
sumCountManyData = putStr "How many integers to sum..? "
                   >>  getLine
                   >>= sequence . flip replicate getLine . read
                   >>= print . sum . map read