Search code examples
haskellfunctional-programmingstdoutstdin

Haskell read first n lines


I'm trying to learn Haskell to get used to functional programming languages. I've decided to try a few problems at interviewstreet to start out. I'm having trouble reading from stdin and doing io in general with haskell's lazy io.

Most of the problems have data coming from stdin in the following form:

n
data line 1
data line 2
data line 3
...
data line n

where n is the number of following lines coming from stdin and the next lines are the data.

How do I run my program on each of the n lines one at a time and return the solution to stdout?

I know the stdin input won't be very large but I'm asking about evaluating each line one at a time pretending the input is larger than what can fit in memory just to learn how to use haskell.


Solution

  • You can use interact, in conjunction with lines to process data from stdin one line at a time. Here's an example program that uses interact to access stdin, lines to split the data on each newline, a list comprehension to apply the function perLine to each line of the input, and unlines to put the output from perLine back together again.

    main = interact processInput
    
    processInput input = unlines [perLine line | line <- lines input]
    
    perLine line = reverse line -- do whatever you want to 'line' here!
    

    You don't need to worry about the size of the data you're getting over stdin; Haskell's laziness ensures that you only keep the parts you're actually working on in memory at any time.

    EDIT: if you still want to work on only the first n lines, you can use the take function in the above example, like this:

    processInput input = unlines [perLine line | line <- take 10 (lines input)]
    

    This will terminate the program after the first ten lines have been read and processed.