11

我正在尝试将内容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]

我怎样才能做到这一点?

4

2 回答 2

53

使用replicateM来自Control.Monad

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

本着“授人以鱼/授人以渔”的精神:您可以通过搜索Hoogle自己找到此内容。

你有:

  • 要执行的动作类型IO String
  • 执行该操作的次数(类型Int

你要:

  • 类型的动作IO [String]

因此,您可以在Hoogle 中搜索(IO String) -> Int -> (IO [String]). replicateM是第一个打击。

于 2012-04-23T18:22:02.093 回答
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
于 2017-05-25T16:16:55.433 回答