ErisoHV
ErisoHV

Reputation: 377

How do I read N lines in a file with Haskell?

I have a file in the form:

3
1 2
3 4
5 7

Where the first line is the number of lines

I know that:

getInt :: IO Int
getInt = readLn 

main = do num <- getInt
          print (num)

Reads the first line.

Next, I tried:

readInts :: IO [Int]
readInts = fmap (map read.words) getLine

For read a line and get a list: [a,b].

And I tried to use the above in a recursive loop

loop :: Int -> IO()
loop n = if 1 == n then do num <- readInts 
                           print(num)
        else loop (n-1)

I'm getting the first line only:

[5,3]

But I need to read the rest of lines, given N

Upvotes: 1

Views: 1500

Answers (3)

ggorlen
ggorlen

Reputation: 56895

Adding to this helpful answer and comment, for some challenges you'll need to collect n lines and then emit a single result at the end based on an aggregation of the data. An approach for creating a list might use replicateM as follows:

import Control.Monad

toInt :: String -> Int
toInt x = read x :: Int

lineToInts :: String -> [Int]
lineToInts x = map toInt $ words x

main :: IO ()
main = do
    n <- readLn
    remainingLines <- replicateM n getLine
    let list = map lineToInts remainingLines
    print list

Sample run:

3
0 1
3 4
6 8
[[0,1],[3,4],[6,8]]

See also Read n lines input with Haskell

Upvotes: 1

castletheperson
castletheperson

Reputation: 33466

The format of the input file looks a lot like the ones used in programming contests. Here is my standard setup for programming contests like that:

import Control.Monad
import Text.Printf

main :: IO ()
main = do
    n <- readLn
    forM_ [1 .. n] $ \i -> do
        printf "Case %d: " (i :: Int)
        solve

An example of solve might be:

solve :: IO ()
solve = do
    nums <- map read . words <$> getLine
    print (sum nums)

Upvotes: 3

Yotam Ohad
Yotam Ohad

Reputation: 322

Have you looked into the function lines? It takes a string and returns the same string as a list separated by \n. Using this function you don't even have to have the number of lines.

Upvotes: 0

Related Questions