user1349427
user1349427

Reputation: 165

Read n lines into a [String]

I'm trying to read n lines of content into a List of Strings. I've tried several variations of the code below, but nothing worked.

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

This throws the following error:

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 }

And

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

throws

 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]

How can I do this?

Upvotes: 11

Views: 6253

Answers (2)

Redu
Redu

Reputation: 26161

One other way you can do this action is by using the pure replicate and the sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) tool. Lets say first we will ask for a count and then ask for that many integers to print their sum on the terminal.

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

Upvotes: 2

dave4420
dave4420

Reputation: 47052

Use replicateM from Control.Monad:

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

In the spirit of give a man a fish / teach a man to fish: You could have found this yourself by searching Hoogle.

You have:

  • an action to perform of type IO String
  • a number of times to perform that action (type Int)

You want:

  • an action of type IO [String]

So you could search Hoogle for (IO String) -> Int -> (IO [String]). replicateM is the first hit.

Upvotes: 54

Related Questions