Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read n lines into a [String]

Tags:

haskell

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?

like image 671
user1349427 Avatar asked Apr 23 '12 18:04

user1349427


1 Answers

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.

like image 105
dave4420 Avatar answered Sep 22 '22 21:09

dave4420