Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - loop over user input

Tags:

io

haskell

I have a program in haskell that has to read arbitrary lines of input from the user and when the user is finished the accumulated input has to be sent to a function.

In an imperative programming language this would look like this:

content = ''
while True:
    line = readLine()
    if line == 'q':
        break
    content += line
func(content)

I find this incredibly difficult to do in haskell so I would like to know if there's an haskell equivalent.

like image 236
user2073343 Avatar asked Sep 02 '13 12:09

user2073343


1 Answers

The Haskell equivalent to iteration is recursion. You would also need to work in the IO monad, if you have to read lines of input. The general picture is:

import Control.Monad

main = do
  line <- getLine
  unless (line == "q") $ do
    -- process line
    main

If you just want to accumulate all read lines in content, you don't have to do that. Just use getContents which will retrieve (lazily) all user input. Just stop when you see the 'q'. In quite idiomatic Haskell, all reading could be done in a single line of code:

main = mapM_ process . takeWhile (/= "q") . lines =<< getContents
  where process line = do -- whatever you like, e.g.
                          putStrLn line

If you read the first line of code from right to left, it says:

  1. get everything that the user will provide as input (never fear, this is lazy);

  2. split it in lines as it comes;

  3. only take lines as long as they're not equal to "q", stop when you see such a line;

  4. and call process for each line.

If you didn't figure it out already, you need to read carefully a Haskell tutorial!

like image 168
nickie Avatar answered Oct 14 '22 18:10

nickie